我有一些如下所示的通用方法。
通过以这种方式定义方法,Scala 无法推断出类型 A 和 B 出于某种原因。
def someMethod[A <: UpperBoundA, B <: UpperBoundB](m: Map[A, B], condition: A => Boolean): Option[B] =
m.filterKeys(condition).headOption.map(_._2)
Run Code Online (Sandbox Code Playgroud)
但是当通过应用柯里化转换如下方法时,Scala 设法正确推断类型。
def someMethod[A <: UpperBoundA, B <: UpperBoundB](m: Map[A, B])(condition: A => Boolean): Option[B] =
m.filterKeys(condition).headOption.map(_._2)
Run Code Online (Sandbox Code Playgroud)
以下是所有方法的调用方式
someMethod(m, _.someField == "aaa") // not working for some reason
someMethod[Key, Value](m, _.id == "aaa") // working
someMethod(m)(_.someField == "aaa") // working(with currying)
Run Code Online (Sandbox Code Playgroud)
这是为什么?
除非这些参数位于不同的参数组中,否则编译器无法使用对一个参数的推断来帮助解析另一个参数。
参数值也是一样。
def f(x:Int = 4, y:Int = x) :Int = x*y //Error: not found: value x
def f(x:Int = 4)(y:Int = x) :Int = x*y //OK, 2 default values
Run Code Online (Sandbox Code Playgroud)
编译器在移动到第二个参数组之前解析第一个参数组,从第一个参数组获得的信息可供第二个使用。