В scala невозможно требовать неявного преобразования для типа
параметр черты. Для этого есть веская причина. Предположим, мы определили
черта типа:
trait ATrait[T <% Int] {
def method(v: T) { println(v: Int) }
}
А затем сделал это в двух местах:
package place1 {
implicit def strToInt(s: String) = 5
val inst = new ATrait[String]
}
package place2 {
implicit def strToInt(s: String) = 6
val inst = new ATrait[String]
}
А потом использовал такие экземпляры как:
val a = if (someTest) place1 else place2
a.method("Hello")
Должен ли этот отпечаток 5
или 6
? То есть какое неявное преобразование следует использовать?
Последствия должны быть найдены во время компиляции, но вы не знаете, какие неявные
преобразование присутствовало для создания объекта.
Другими словами, последствия обеспечиваются областью, в которой они используются, а не
объектами, на которых они используются; последнее было бы невозможно.
Итак, о вашей проблеме. Вместо использования неявного, вы можете использовать обычный
член:
trait Summable[T] {
def -= (v: T): Unit
def -= (v: Int) { this -= (encode(v)) }
def encode(i: Int): T
}
class Int4 (var x: Int, var y: Int, var z: Int, var w: Int) extends Summable[Int4] {
def -= (v : Int4) : Unit = { x -= v.x; y -= v.y; z -= v.z; w -= v.w }
def encode(i: Int) = Int4.int2Int4(i)
}
Теперь метод decrement
компилируется правильно.
Другой способ сказать это - не думать о последствиях как о свойствах, принадлежащих
к типу (то есть, «может быть неявно преобразован из Int» не является свойством
INT4). Это значения, которые можно идентифицировать с помощью типов.
Надеюсь, это поможет.