Scala 确保块中的隐式转换失败
Failed implicit conversion in scala ensuring block
我正在使用 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)
,则程序编译成功。所以我很疑惑。为什么我会看到这种行为?有没有办法在没有显式转换的情况下防止这个错误?
谢谢!
这个有效:
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
的东西。它还能做什么?类型检查器以非常直接的方式工作。它只是查看一个表达式,尝试导出它的最精确类型,如果没有从外部指定类型,它不会尝试隐式转换任何内容。而且它不会开始在代码的偏远角落搜索其他类型提示。在这种情况下,ensuring ( ... )
既不是该表达式的一部分,也不允许显式 return 类型归属 : Int64 =
向下渗透。
我想理解为什么这很明显的最好方法是为简单类型的 lambda 演算编写一个小的类型检查器:它非常简单,但在类似情况下已经表现出完全相同的行为。
我正在使用 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)
,则程序编译成功。所以我很疑惑。为什么我会看到这种行为?有没有办法在没有显式转换的情况下防止这个错误?
谢谢!
这个有效:
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
的东西。它还能做什么?类型检查器以非常直接的方式工作。它只是查看一个表达式,尝试导出它的最精确类型,如果没有从外部指定类型,它不会尝试隐式转换任何内容。而且它不会开始在代码的偏远角落搜索其他类型提示。在这种情况下,ensuring ( ... )
既不是该表达式的一部分,也不允许显式 return 类型归属 : Int64 =
向下渗透。
我想理解为什么这很明显的最好方法是为简单类型的 lambda 演算编写一个小的类型检查器:它非常简单,但在类似情况下已经表现出完全相同的行为。