我刚开始学习Scala,来自Java背景。我一直在尝试理解函数中的类型参数和类型的推断。这是Scala文档中的标准示例:
class Decorator(left: String, right: String) {
def layout[A](x: A) = left + x.toString() + right
}
object FunTest extends Application {
def apply(f: Int => String, v: Int) = f(v)
val decorator = new Decorator("[", "]")
println(apply(decorator.layout, 7))
}
如果我尝试将类型参数应用于apply
函数并将v
保持为强类型,则会出现类型不匹配。为什么不在这里推断类型?
def apply[B](f: B => String, v: String) = f(v) //Type mismatch
def apply[B](f: B => String, v: B) = f(v) //Works fine
由于
答案 0 :(得分:1)
让我们看一下没有身体的apply
:
def apply[B](f: B => String, v: String)
其中显示“apply
是在B
类型上参数化的函数(方法),它从B
到String
以及String
执行函数}”。
将B
视为类型变量;它需要在某个时刻进行实例化。这一点是不 apply
的声明。适用时,适用于; - )
通过这份合同,必须允许这样使用:
def g(i: Int): String = "i is " + i
apply(g, "foo") // Here the type variable `B` is "instantiated" to the type Int,
但鉴于你有一个像f(v)
的身体,只是替换,我们看到矛盾:
替代
f(v)
使用
g("foo") // can't compile; g takes a B, which is an Int