隐含的转换怪异

Dim*_*ima 11 scala implicit-conversion

我试图理解为什么一个隐式转换在一个案例中起作用,而在另一个案例中却没有.这是一个例子:

   case class Wrapper[T](wrapped: T)
   trait Wrapping { implicit def wrapIt[T](x: Option[T]) = x.map(Wrapper(_))

   class NotWorking extends Wrapping { def foo: Option[Wrapper[String]] = Some("foo") }

   class Working extends Wrapping { 
      def foo: Option[Wrapper[String]] = {
        val why = Some("foo")
        why
      }
    }
Run Code Online (Sandbox Code Playgroud)

基本上,我有从隐式转换Option[T]Option[Wrapper[T]],并正在试图定义一个函数,该函数返回一个可选的字符串,是被隐式包装.

问题是,当我尝试Option[String]直接返回(NotWorking上面)时,我得到一个错误(found : String("foo") required: Wrapper[String]),如果我在返回之前将结果分配给val,那就会消失.

是什么赋予了?

Jas*_*r-M 10

我不知道这是故意还是被认为是一个错误,但这是我认为正在发生的事情.

def foo: Option[Wrapper[String]] = Some("foo")编译器中将提供的参数的预期类型设置为Some( )as Wrapper[String].然后它看到你提供的String不是预期的,所以它寻找隐式转换String => Wrapper[String],找不到,失败.

为什么它需要的是预期的类型的东西,不只是输入Some("foo")Some[String]事后试图找到一个转换?因为scalac希望能够检查以下代码:

case class Invariant[T](t: T)
val a: Invariant[Any] = Invariant("s")
Run Code Online (Sandbox Code Playgroud)

为了使这个代码能够工作,编译器不能只键入Invariant("s")as,Invariant[String]因为编译将失败,因为Invariant[String]它不是子类型Invariant[Any].编译器需要设置的期望类型"s",以Any使其可以看出"s"是一个实例Any,为时已晚之前.

为了使这段代码和你的代码能够正确地运行,我认为编译器需要一些它似乎没有的回溯逻辑,也许是有充分理由的.

您的Working代码确实有效的原因是这种类型推断不会跨越多行.类似val a: Invariant[Any] = {val why = Invariant("s"); why}不能编译.