Ошибка получения несоответствия типа getOrElse
Почему этот код вызывает ошибку несоответствия типа в Scala 2.9.2? Я ожидал, что getOrElse
возвращает тип String
, но на самом деле он возвращает java.io.Serializable
:
scala> implicit def StringToOption(s:String) = Option(s)
StringToOption: (s: String)Option[String]
scala> "a".getOrElse("")
res0: String = a
scala> var opt:Option[String] = "a".getOrElse("")
<console>:8: error: type mismatch;
found : java.io.Serializable
required: Option[String]
var opt:Option[String] = "a".getOrElse("")
^
Это нормально:
scala> implicit def StringToOption(s:String): Option[String] = Option(s)
StringToOption: (s: String)Option[String]
scala> var b:Option[String] = "a".getOrElse("") toString
b: Option[String] = Some(a)
Ответы
Ответ 1
Это нежелательный случай неполного обхода дерева. Подпись getOrElse
позволяет расширять тип, поэтому, когда он понимает, что String
не является Option[String]
, он сначала пытается заполнить другой тип подписки на getOrElse
, т.е. Serializable
. Но теперь он имеет "a".getOrElse[Serializable]("")
и он застрял - он не понимает, я думаю, что проблема делала тип слишком общим, прежде чем проверять наличие имплицитов.
Как только вы осознаете проблему, есть исправление:
"a".getOrElse[String]("")
Теперь типер не блуждает по пути let's-widen и находит неявное.