gpt4 book ai didi

scala - 当对Option.getOrElse的返回值使用隐式转换时,为什么在Scala中类型推断失败?

转载 作者:行者123 更新时间:2023-12-02 10:42:53 24 4
gpt4 key购买 nike

例如,我有一个Value类和一个将字符串转换为Value的隐式函数:

case class Value(v: String)

implicit def strToValue(s: String): Value = Value(s)

这是一个具有方法返回Value的特征:
trait ReturnValue {
def f: Value
}

因为存在隐式转换,所以我可以通过返回String文字来实现方法f:
object Obj1 extends ReturnValue {
override def f: Value = "123"
}

当然返回一个String类型的变量也可以:
object Obj2 extends ReturnValue {
override def f: Value = {
val v = Some("123").getOrElse("234")
v
}
}

但是,当我尝试直接使用Option.getOrElse的结果作为返回值时:
object Obj3 extends ReturnValue {
override def f: Value = Some("123").getOrElse("234") // Compilation error: type mismatch
}

发生编译错误:
Error:(23, 50) type mismatch;
found : java.io.Serializable
required: Entry.Value
override def f: Value = Some("123").getOrElse("234") // Compilation error: type mismatch

看来这里的类型推断失败了。不推断字符串类型,则隐式转换无法匹配。 (完整文件为 here)

我尝试了其他具有类型参数的函数,例如“map”,它们都可以正常工作。

为什么Option.getOrElse如此特别,以至于类型推断在这里失败了?

最佳答案

此变体导致相同的编译错误,并可能显示编译器如何解构表达式:

object Obj3 extends ReturnValue {
override def f: Value = {
val v = Some("123") // is of type Some(String)
v.getOrElse("234": Value) // Compilation error: type mismatch
}
}

通过以下简单的复制,也可以实现相同的错误而没有任何特征:
case class Value(v: String)

implicit def strToValue(s: String): Value = Value(s)

val vs = Some("123")

val v: Value = vs.getOrElse("234")

似乎编译器将转换转换为 Value的参数上的 getOrElse,而不是其结果上。事实是可以通过启用 scalacOptions in Compile ++= Seq("-Xprint-types", "-Xprint:typer")的输出来确认(清除了一点-删除了明显不相关的注释):

private[this] val v: Value =

vs.getOrElse{[B >: String](default: => B)B}[java.io.Serializable]{(default: => java.io.Serializable)java.io.Serializable}( strToValue{(s: String)Value}("234"{String("234")}){Value} ){



我认为推论如下:
  • vs类型称为Some[String]
  • getOrElse声明是def getOrElse[B >: A](default: => B): B(此处AString)
  • 编译器将B推断为Value,因为这是表达式的预期结果类型。
  • ValueString最具体的父类(super class)型是Serializable

  • 您还可以注意完全删除隐式转换后的行为。那么 val v: Value = vs.getOrElse("234")的错误是: 类型不匹配;
    找到:字符串(“234”)
    必需:值

    关于scala - 当对Option.getOrElse的返回值使用隐式转换时,为什么在Scala中类型推断失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56934944/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com