当我这样做时:
def x(i: Int, i2: Int, i3: Int) = i
x(_: Int, _: Int, 3)
为什么我必须指定前两个参数是“Int”?
有没有办法让编译器推断类型,以便我可以输入:
x(_, _, 3)
答案 0 :(得分:1)
简答:
除非需要函数类型,否则您必须明确指出匿名函数的参数类型。 “部分应用程序”只是用于创建匿名函数的语法糖。
答案很长:
首先,请注意,部分应用x
时,总是不得提供类型参数。考虑这个例子:
def x(i: Int, i1: Int, i2: Int) = i
def g(f: (Int, Int) => Int) = f(1, 2)
// types are inferred!
g(x(_, _, 3)) // evaluates to 1
// again, types are inferred
val f: (Int, Int) => Int = x(_, _, 3)
很明显,在预期(Int, Int) => Int
的情况下,它会有所帮助。
其次,请注意您正在定义匿名函数。您可以更明确地编写它:
(a, b) => x(a, b, 3)
以这种方式编写,应该更清楚的是,定义上下文(即,作为单独的表达式)不会对匿名函数的类型产生任何期望。另一方面,在g
的应用中,g
的参数类型意味着对特定函数类型的期望。
原则上,编译器可以从a
的类型推断出b
和x
的类型,但它没有,如{{3的§6.23中所指定的那样(粗体强调添加):
匿名函数( x 1 : T 1 ,..., x < sub> n : T n )=&gt; e 将 T i 类型的参数 x i 映射到表达式给出的结果ë。 [...]
如果预期的匿名函数类型的格式为scala.FunctionN [ S 1 ,..., S n , R ], e 的预期类型是 R ,类型 T i <任何参数 x i 的/ sub> 都可以省略,在这种情况下 T i = S i 。 如果匿名函数的预期类型是其他类型,则必须明确指定所有形式参数类型,并且 e 的预期类型未定义。