Ответ 1
Я не знаю, было ли это предназначено или будет считаться ошибкой, но вот что я думаю, что происходит.
В def foo: Option[Wrapper[String]] = Some("foo")
компилятор задает ожидаемый тип аргумента, предоставленного Some( )
, как Wrapper[String]
. Затем он видит, что вы предоставили String
, который не является ожидаемым, поэтому он ищет неявное преобразование String => Wrapper[String]
, не может найти его и терпит неудачу.
Зачем ему нужен этот тип ожидаемого типа и не просто набирает Some("foo")
как Some[String]
, а потом пытается найти преобразование?
Поскольку scalac хочет иметь возможность проверять следующий код:
case class Invariant[T](t: T)
val a: Invariant[Any] = Invariant("s")
Чтобы этот код работал, компилятор не может просто набрать Invariant("s")
как Invariant[String]
, потому что тогда компиляция завершится неудачно, поскольку Invariant[String]
не является подтипом Invariant[Any]
. Компилятору необходимо установить ожидаемый тип "s"
на Any
, чтобы он мог видеть, что "s"
является экземпляром Any
до того, как он слишком поздно.
Для того, чтобы как этот код, так и ваш код работали правильно, я думаю, что компилятору понадобится какая-то логика обратного отслеживания, которая, по-видимому, не имеет, возможно, по уважительным причинам.
Причина, по которой ваш код Working
работает, заключается в том, что такой тип вывода не охватывает несколько строк. Аналогично val a: Invariant[Any] = {val why = Invariant("s"); why}
не компилируется.