Это означает, что Option [Nothing] является подтипом опции [Int] (из-за ковариации), правильно?
Исправить. Option[Nothing]
- Option[Int]
.
Но с B>: A мы сказали, что B должен быть супертипом ?! Итак, как мы можем получить Int обратно?
Это не должно быть супертип. Он просто требует A
как нижняя граница. Это означает, что вы все равно можете пройти Int
до getOrElse
, если A
- Int
.
Но это не значит, что вы не можете передавать экземпляры подкласса. Например:
class A
class B extends A
class C extends B
scala> Option(new B)
res196: Option[B] = Some([email protected])
scala> res196.getOrElse(new C)
res197: B = [email protected]
scala> res196.getOrElse(new A)
res198: A = [email protected]
scala> res196.getOrElse("...")
res199: Object = [email protected]
Я все еще могу передать экземпляр C
, потому что C
может быть до литого к B
. Я также могу передать тип выше дерева наследования, а getOrElse
вернет этот тип. Если я передаю тип, который не имеет ничего общего с типом, содержащимся в Option
, тогда будет выведен тип с наименьшей верхней границей. В приведенном выше случае это Any
.
Так почему же существует нижняя граница там вообще? Почему нет:
def getOrElse[B <: A](default: => B): B
Это не будет работать, потому что getOrElse
должен либо вернуть A
, содержащуюся в Option
, или по умолчанию B
. Но если мы вернем A
и A
не является B
, поэтому привязка типа недействительна.Возможно, если getOrElse
вернулся A
:
def getOrElse[B <: A](default: => B): A
Это будет работать (если бы это было на самом деле определено, что путь), но вы были бы ограничены по типу-часам. Поэтому в приведенном выше примере вы можете пройти только B
или C
до getOrElse
по адресу Option[B]
. В любом случае, это не так, как в стандартной библиотеке.
Стандартная библиотека getOrElse
позволяет передавать что-либо к нему. Скажем, у вас есть Option[A]
. Если мы передадим подтип A
, он будет добавлен к A
. Если мы пройдем A
, очевидно, это нормально. И если мы передадим какой-то другой тип, то компилятор отображает наименьшую верхнюю границу между ними. Во всех случаях выполняется привязка типа B >: A
.
Потому что getOrElse
позволяет вам что-либо передать, многие считают это очень сложным. Например, вы могли бы:
val number = "blah"
// ... lots of code
val result = Option(1).getOrElse(number)
И это скомпилируется. У нас будет только Option[Any]
, который, вероятно, вызовет ошибку в другом месте.
Спасибо, но не могли бы вы привести пример того, какой тип мы не смогли бы передать res196.getOrElse ... В настоящее время, с этим примером, я не вижу смысла иметь нижнюю границу. Или, лучше сказать, я теперь не понимаю, что это означает, что тип является нижней границей ... – Marin
@Marin Вы можете передать любой тип 'getOrElse'. См. Мое редактирование. –
спасибо! Кажется, я понял это сейчас. – Marin