2010-08-27 5 views
4

Scala 2.8 спецификации сказано в разделе 7.3 (выделение мое):Почему неявное преобразование из Long в RichLong не применяется там, где ожидается супертип RichLong?

неявные параметры и методы могут также определить неявные преобразования, называемые видами. Вид из типа S в тип T определяется неявным значением, которое имеет тип функции S => T или (=> S) => T или методом, конвертируемым в значение этого типа. Представления применяются в двух ситуациях.

  1. Если выражение е типа Т и Т не соответствует к ожидаемого типа пт выражения. В этом случае выполняется поиск неявного v, который применим к e и , тип результата которого соответствует по pt. Поиск продолжается, как в случае с неявными параметрами , где неявная область - одна из T => pt. Если такой вид найден, выражение e преобразуется в v (e).

[...]

приведены выше, и следующие факты:

  1. Long не является подтипом java.lang.Comparable[Long], т.е. не соответствует к типу T где T <: java.lang.Comaparable[Long]
  2. Predef содержит implicit def longWrapper (x: Long) : RichLong
  3. RichLong является подтипом java.lang.Comparable[Long], т.е. соответствует к типу T где T <: java.lang.Comaparable[Long]

Я хотел бы ожидать, что неявное преобразование следует применять, когда Long встречается и подтипом java.lang.Comparable[Long] ожидается. Однако:

scala> def test[T <: java.lang.Comparable[Long]](c: T) = println(c) 
test: [T <: java.lang.Comparable[Long]](c: T)Unit 

scala> test(12L) 
<console>:7: error: inferred type arguments [Long] do not conform to method test's type parameter bounds [T <: java.lang 
.Comparable[Long]] 
     test(12L) 
    ^

В результате, как ожидается, если значение преобразуется в явном виде:

scala> test(longWrapper(12L)) 
12 

Почему функция преобразования не применяется неявно?

ответ

5

Для просмотра компилятора и применения неявного преобразования вам необходимо использовать связанный с просмотром (<%).

scala> def test[T <% java.lang.Comparable[Long]](c: T) = println(c) 
test: [T](c: T)(implicit evidence$1: (T) => java.lang.Comparable[Long])Unit 

scala> test(12L) 
12 

Вы можете прочитать больше о целях переплете на this странице (Ctrl + F для "вид связан").

+0

Спасибо, вам нужно будет читать по границам типа, по-видимому! –