【发布时间】:2021-06-09 21:06:29
【问题描述】:
我在尝试练习 scala 面试问题时发现“对重载定义的模糊引用”。
我试图找到导致编译错误的以下代码块的结果:
代码:
for {
v1 <- Left[Int,Int](1)
v2 <- Right(2)
v3 <- Right(3)
v4 <- Left(4)
} yield v1 + v2 + v3 + v4
错误:
<pastie>:17: error: ambiguous reference to overloaded definition,
both method + in class Int of type (x: Char)Int
and method + in class Int of type (x: Byte)Int
match argument types (Nothing)
} yield v1 + v2 + v3 + v4
^
当我们仅在 v1 字段上指定类型而不在 v4 上指定类型时,为什么 Scala 编译器会给出模糊引用错误?
我还尝试了 v1 和 v4 中具有不同参数类型的以下版本,并且成功了!
for {
v1 <- Left[String,Int]("1")
v2 <- Right(2)
v3 <- Right(3)
v4 <- Left[Int, Int](4)
} yield v1 + v2 + v3 + v4
输出是:
res20: scala.util.Either[Any,Int] = Left(1)
我尝试了另一个版本,但也导致了错误:
for {
v1 <- Left(1)
v2 <- Right(2)
v3 <- Right(3)
v4 <- Left(4)
} yield v1 + v2 + v3 + v4
输出:
<console>:17: error: value + is not a member of Nothing
} yield v1 + v2 + v3 + v4
在这里,Left 和 Right 的 for 理解到底是如何工作的?为什么第一个和最后一个案例在我的示例中不起作用?
【问题讨论】:
-
你在 eithers 上写了一个
for,因此编译器需要同时跟踪 left 和 right i> 类型。您的示例没有提供这些类型,也没有为编译器提供足够的信息来正确推断它们。例如v4 <- Left(4)v4的类型应该是什么?对你来说很明显它应该是 Int 但对于编译器来说它简单不知道,所以它假设 Nothing 但你不能总结一个 Int 带有 Nothing。一般来说,这不是问题,因为通常您不会有硬编码值(因为您可以手动减少表达式),而是调用方法。 -
@Luis Miguel Mejía Suárez,很好的解释来理解这个问题。但是为什么 scala compile 在我的示例中只为 v1 字段指定类型的第一种情况不会产生任何错误?
-
不确定您的意思?第一个版本确实会产生错误。