我写了一个课程,期望获得Option[(E) => Long]
:
class Whatever[E] (sizeFunction: Option[(E) => Long])
当我尝试使用函数(E) => Int
实例化它时:
val sizeFunction = (a: String) => a.length
new Whatever[String](Some(sizeFunction))
我收到编译错误:
type mismatch;
found : String => Int
required: String => Long
不应该String => Int
"满足" String => Long
由于扩大了?
答案 0 :(得分:2)
请记住String => Int本身就是一种类型。 String =>长是一种不同的类型。这对某些程序很重要,对于其他程序并不重要,如您的示例所示。但是编译器做出假设而不是调用类型不匹配会很危险,因为它可能会扩展函数类型的一部分。如果你真的在乎你可以将sizeFunction定义为String =>号。
答案 1 :(得分:2)
在Scala中,函数的返回类型为协变:要使A => B
成为A => C
的子类型,B
必须是{{1}的子类型1}}。但C
不是Int
的子类型(即“每Long
为Int
”并非如此;)相反,它可以扩展为Long
,这是一种不同的关系。
协方差的定义可能可以更改为Long
必须弱地符合而不是B
(即C
是B
的子类型,或者可以扩展为C
,或者C
和B
之间存在一系列中间类型,其中上述类型之一成立。但是为了保持一致,同样必须适用于逆变:C
将是Long => A
的子类型(通过应用扩展到参数)。这对我来说似乎不是一个好主意(并且只改变协方差,但不是逆变,似乎更糟)。