gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 01:52:52 25 4
gpt4 key购买 nike

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

case class Value(v: String)

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

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

因为隐式转换存在,我可以通过只返回一个字符串文字来实现方法 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

看来这里的类型推断失败了。类型 String 没有被推断出来,然后就无法匹配到隐式转换。 (完整文件是 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 此处)
  • 编译器推断 BValue ,因为这是表达式的预期结果类型。
  • Value的最具体的父类(super class)型和 StringSerializable

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

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

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