我使用scalac 2.12.1编译以下程序而没有任何选项:
import scala.language.implicitConversions
case class Int32(v : Int) {
}
case class Int64(v : BigInt) {
def > (that : Int64) = this.v > that.v
def <= (that : Int64) = this.v <= that.v
}
object implicits {
implicit def int32Toint64(input : Int32) = Int64(BigInt(input.v))
}
import implicits._
class myTest {
def max(x: Int64, y: Int32) : Int64 = {
if (x > y)
x
else
y // If this is replaced with int32Toint64(y) it works !
} ensuring(res => x <= res && y <= res) // <= error: missing parameter type for 'res'
}
上述程序无法使用注释中指示的错误进行编译。
我的期望是隐式转换int32Toint64
将自动生效。请注意,如果我明确进行转换,即如果我将y
替换为int32Toint64(y)
,则程序会成功编译。所以我很困惑。为什么我会看到这种行为?有没有办法在没有显式转换的情况下阻止此错误?
谢谢!
答案 0 :(得分:2)
这有效:
class myTest {
def max(x: Int64, y: Int32) : Int64 = {
if (x > y)
x
else
(y : Int64)
} ensuring(res => x <= res && y <= res)
}
这也有效:
class myTest {
def max(x: Int64, y: Int32) : Int64 = ({
if (x > y)
x
else
y
}: Int64) ensuring(res => x <= res && y <= res)
}
这显然不起作用:
class myTest {
def max(x: Int64, y: Int32) : Int64 = {
if (x > y)
x
else
y
} ensuring((res: Int64) => x <= res && y <= res)
}
为什么呢?单独看一下这个表达式:
{
if (x > y)
x
else
y
}
如果类型没有明确归属,编译器可能会得到什么?它会得到类似Serializable
甚至AnyRef
的内容。它还能做什么? typechecker以非常直接的方式工作。它只是查看一个表达式,试图导出它的最精确类型,如果没有从外部规定类型,它就不会试图隐式地抛出任何东西。并且它不会开始在代码的远程角落搜索其他类型提示。在这种情况下,ensuring ( ... )
既不是此表达式的一部分,也不允许显式返回类型ascription : Int64 =
向下删除。
我想理解为什么这是显而易见的最好方法是为简单类型的lambda演算编写一个小类搜索器:它非常简单,但它在类似的情况下已经表现出完全相同的行为。