Почему неявное преобразование из Long в RichLong не применяется там, где ожидается супертип RichLong? - PullRequest
4 голосов
/ 27 августа 2010

Спецификация Scala 2.8 говорит в разделе 7.3 (выделение мое):

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

  1. Если выражение e имеет тип T, а T не соответствует ожидаемому типу выражения pt.В этом случае ищется неявный 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

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

1 Ответ

5 голосов
/ 27 августа 2010

Вам нужно использовать привязку вида (<%), чтобы компилятор искал и применял неявное преобразование.

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

Подробнее о привязке к просмотру можно прочитать на этой странице (Ctrl + F для «просмотра привязки»).

...