Scala-定义自己的中缀运算符 [英] Scala - defining own infix operators

查看:139
本文介绍了Scala-定义自己的中缀运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

采用单个参数的方法可以在Scal中编写为中缀运算符. IE.将*(other:C) = foo(this, other)添加到类C,将允许我们编写c1 * c2而不是foo(c1,c2).但是有没有办法在无法修改的现有类上定义中缀运算符?

Methods taking a single argument can be written as an infix operators in Scal. I.e. adding *(other:C) = foo(this, other) to class C, will allow us to write c1 * c2 instead of foo(c1,c2). But is there a way to define infix operators on existing classes that you cannot modify?

例如如果我想写c1 + c2而不是xor(c1,c2),而我写的是c1,c2:Array[Byte],显然我不能修改Array-Class.

E.g. if I wanted to write c1 + c2 instead of xor(c1,c2), where c1,c2:Array[Byte], I obviously cannot modify the Array-Class.

我找到了并尝试了

implicit class Bytearray(a1:Array[Byte]) extends Anyval {
    def +(a2:Array[Byte]) = xor(a1,a2)
}

但这似乎不起作用(c1 + c2).

But that doesn't seem to work (c1 + c2).

类型不匹配,应为:字符串,实际为:数组[字节]

Type mismatch, expected:String, actual:Array[Byte]

我认为问题可能出在我使用+的问题上,所以我将其交换为xorc1 xor c2仅导致

I thought that perhaps the issue was my using +, so I exchanged it for xor but c1 xor c2 only lead to

无法解析符号xor

Cannot resolve symbol xor

有什么建议吗?

更新

有趣.我有一个class Foo,在其下定义了object Foo,其中包含隐式类.这会导致上述错误.

Interesting. I had a class Foo with an object Foo defined below it, containing the implicit class. This lead to the aforementioned errors.

但是,删除对象,然后将隐式类放入trait BytearrayHandling中,然后对其进行扩展(class Foo extends BytearrayHandling)似乎可行.为什么呢?

However, deleting the object and instead putting the implicit class into a trait BytearrayHandling and then extending it (class Foo extends BytearrayHandling) seems to work. Why is that?

推荐答案

使用扩展方法的常规声明应该很简单:

It should be straight forward with the normal declaration of extension methods:

implicit class ByteArrayOps(private val a1: Array[Byte]) extends AnyVal {
  def + (a2: Array[Byte]): Array[Byte] = 
    (a1 zip a2).map { case (x, y) => (x ^ y).toByte }
}

"foo".getBytes + "bar".getBytes  // Array(4, 14, 29)


但是请注意,有时您会遇到这种情况:


However be aware that sometimes you will run into this:

类型不匹配,应为:字符串,实际为:X

Type mismatch, expected:String, actual: X

这是因为有一个隐式转换,它允许您通过将+转换为字符串来进行任何操作.我有已给出 尝试 了解如何将其停用.如果我没有记错的话,它将最终在Scala 2.12中使用.

This is because of an implicit conversion kicking in that allows you to + anything by converting it to a String. I have given up trying to understand how to deactivate it. It will finally go in Scala 2.12 if I'm not mistaken.

正如eugener指出的那样,此错误消息可能表示您实际上尚未导入扩展方法(隐式转换).例如:

As eugener pointed out, this error message may indicate that you haven't actually imported your extension method (implicit conversion). For example:

object MyStuff {
  implicit class ByteArrayOps(private val a1: Array[Byte]) extends AnyVal {
    def + (a2: Array[Byte]): Array[Byte] = 
      (a1 zip a2).map { case (x, y) => (x ^ y).toByte }
  }
}

"foo".getBytes + "bar".getBytes  // error

给予:

<console>:14: error: type mismatch;
 found   : Array[Byte]
 required: String
              "foo".getBytes + "bar".getBytes
                                     ^

因为此Predef转换. import MyStuff.ByteArrayOps之后,它就会起作用.

because of this Predef conversion. After you import MyStuff.ByteArrayOps, it works.

这篇关于Scala-定义自己的中缀运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆