采用单个参数的方法可以写为Scal中的中缀运算符。即将*(other:C) = foo(this, other)
添加到C类,将允许我们编写c1 * c2
而不是foo(c1,c2)。但有没有办法在现有的类上定义中缀操作符,你无法修改?
E.g。如果我想写c1 + c2
而不是xor(c1,c2)
,c1,c2:Array[Byte]
,我显然无法修改数组类。
我找到了this并尝试了
implicit class Bytearray(a1:Array[Byte]) extends Anyval {
def +(a2:Array[Byte]) = xor(a1,a2)
}
但这似乎不起作用(c1 + c2
)。
类型不匹配,预期:字符串,实际:数组[字节]
我认为问题可能是我使用+
,所以我将其交换为xor
但c1 xor c2
只会导致
无法解析符号xor
有什么建议吗?
更新
有趣。我有一个class Foo
,其下面定义了object Foo
,包含隐式类。这导致了上述错误。
然而,删除对象,而是将隐式类放入trait BytearrayHandling
然后扩展它(class Foo extends BytearrayHandling
)似乎可行。那是为什么?
答案 0 :(得分:6)
应该直接使用扩展方法的正常声明:
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)
但请注意,有时你会碰到这个:
类型不匹配,预期:字符串,实际:X
这是因为隐式转换可以让你通过将它转换为String来+
任何东西。我有given up trying to understand如何停用它。如果我没弄错的话,它最终会进入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
之后,它就可以了。
答案 1 :(得分:1)
您可以执行以下操作:
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)
最后一行应该产生Array(1, 2, 3)
。