Чтобы понять, почему это полезно, IttayD provided a nice explanation:
Так что нам хотелось бы, это Защиту orNull[A >: Null] = .....
Но А уже установлен, и мы не хотим, чтобы ограничили его в определении свойства . Поэтому orNull ожидает доказательства того, что A является типом с нулевым значением. Это доказательство в виде неявной переменной (отсюда и название «эв»)
В целом, ограничения типа полезны, когда вы хотите иметь методы (например, orNull
) на общий класс (например Option
) с более конкретными ограничениями (например, Null <: A <: Any
), чем на самом классе (например, A <: Any
).
Это еще одна «функция», которая не встроена в язык, но предоставляется бесплатно благодаря неявным параметрам и аннотации параметров параметров типа. Чтобы понять это, посмотрите на определение <:<
:
// from Predef
sealed abstract class <:<[-From, +To] extends (From => To)
implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x}
Для
scala> Some(1).orNull
<console>:10: error: could not find implicit value for parameter ev: <:<[Null,Int]
Some(1).orNull
компилятор ищет неявное значение типа <:<[Null, Int]
и найти метод def conforms[A]: A <:< A
. Таким образом, должен быть A
, для которого <:<[A, A]
соответствует <:<[Null, Int]
. Нет A
, для которого это выполняется, и в результате компилятор будет жаловаться на недостающее неявное значение.
Однако для
scala> Some("hi").orNull
res21: java.lang.String = hi
нам повезло. Теперь компилятор пытается найти A
, для которого <:<[A, A]
соответствует <:<[Null, String]
. Это работает для A = String
, потому что Null
является подтипом String
, а параметр типа From
класса <:<
определяется как контравариантный).
Как уже упоминалось, самый интуитивный способ думать о ограничениях типа читает его как привязку к типу (т. Е. Читает его как Null <: Int). Null
не соответствует Int
и нет никакого неявного значения для <: < [Null, Int]. С другой стороны, Null
соответствует String
, и компилятор найдет неявный параметр.
Кстати, вот еще related answer.
Увы, исходный код использует `Null <:
2010-12-17 10:49:23