3

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

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

我找到了这个并尝试了

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

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

类型不匹配,预期:String,实际:Array[Byte]

我以为问题可能出在我的使用+上,所以我换了它,xorc1 xor c2只会导致

无法解析符号异或

有什么建议么?

更新

有趣的。我有一个class Fooobject Foo它下面定义的,包含隐式类。这导致了上述错误。

但是,删除对象并将隐式类放入 atrait BytearrayHandling然后扩展它 ( class Foo extends BytearrayHandling) 似乎可行。这是为什么?

4

2 回答 2

8

扩展方法的正常声明应该是直截了当的:

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)

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

类型不匹配,预期:String,实际:X

这是因为隐式转换开始了,它允许您+通过将其转换为字符串来进行任何操作。我已经放弃尝试 了解如何停用它。如果我没记错的话,它最终会出现在 Scala 2.12 中。

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

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,它可以工作。

于 2015-07-04T15:17:31.167 回答
2

您可以执行以下操作:

class ByteArray(self: Array[Byte]) {
  def +(other: Array[Byte]) = Array[Byte](1, 2, 3) // replace with your code
}

implicit def byteArrayPlus(self: Array[Byte]) = new ByteArray(self)

Array[Byte](0, 1, 2) + Array[Byte](0, 2, 3)

最后一行应该 yield Array(1, 2, 3)

于 2015-07-04T15:14:32.683 回答