scala中的隐式转换失败,确保阻止

时间:2018-01-31 17:21:19

标签: scala implicit-conversion implicit

我使用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),则程序会成功编译。所以我很困惑。为什么我会看到这种行为?有没有办法在没有显式转换的情况下阻止此错误?

谢谢!

1 个答案:

答案 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演算编写一个小类搜索器:它非常简单,但它在类似的情况下已经表现出完全相同的行为。