Scala - defining own infix operators

Deadly 提交于 2019-12-01 20:29:57

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:

Type mismatch, expected:String, actual: X

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.

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

gives:

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

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

You can do something like:

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)

the last line of which should yield Array(1, 2, 3).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!