Чтобы понять, почему это полезно, IttayD предоставил приятное объяснение :
Так что нам бы понравилось, это def orNull[A >: Null] = .....
Но A уже установлен, и мы нене хочу ограничивать это в определении черты.Следовательно, orNull ожидает доказательства того, что A является обнуляемым типом.Это доказательство представлено в форме неявной переменной (отсюда и имя 'ev')
Таким образом, ограничения типа полезны, когда вы хотите иметь методы (например, 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).<code>Null не соответствует Int
и не существует неявного значения для <: <[Null, Int].С другой стороны, <code>Null соответствует String
, и компилятор найдет неявный параметр.
Кстати, вот еще один связанный ответ .