这会产生一个匿名函数,正如您所期望的那样(f是一个带有三个参数的函数):
f(_, _, _)
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这不编译,而是给出"缺少参数类型"错误:
f(_, _, 27)
Run Code Online (Sandbox Code Playgroud)
相反,我需要明确指定下划线的类型.Scala不应该能够推断它们,因为它知道函数f的参数类型是什么吗?
ret*_*nym 19
下面的参考资料是Scala语言规范
请考虑以下方法:
def foo(a: Int, b: Int) = 0
Run Code Online (Sandbox Code Playgroud)
Eta Expansion可以将其转换为类型值(Int, Int) => Int
.在以下情况下调用此扩展:
a)_
用于代替参数列表(方法值(§6.7))
val f = foo _
Run Code Online (Sandbox Code Playgroud)
b)省略参数列表,期望的表达式是函数类型(§6.25.2):
val f: (Int, Int) => Int = foo
Run Code Online (Sandbox Code Playgroud)
c)中每一个的参数是_
(一个特例 "的匿名函数占位符语法"的的(§6.23))
val f = foo(_, _)
Run Code Online (Sandbox Code Playgroud)
表达foo(_, 1)
方式不符合Eta Expansion的条件; 它只是扩展到(a) => foo(a, 1)
(§6.23).常规类型推断并不试图弄清楚这一点a: Int
.
如果您正在考虑部分应用程序,我认为这只能用于多个参数列表(而您只有一个):
def plus(x: Int)(y: Int) = x + y //x and y in different parameter lists
val plus10 = plus(10) _ //_ indicates partial application
println(plus10(2)) //prints 12
Run Code Online (Sandbox Code Playgroud)
您的示例很有趣,因为我完全不知道您描述的语法,看起来您可以使用单个参数列表进行部分应用:
scala> def plus2(x: Int, y: Int) = x + y
plus2: (x: Int,y: Int)Int
scala> val anon = plus2(_,_)
anon: (Int, Int) => Int = <function2>
scala> anon(3, 4)
res1: Int = 7
Run Code Online (Sandbox Code Playgroud)
所以编译器可以清楚地推断出类型Int
!
scala> val anon2 = plus2(20,_)
<console>:5: error: missing parameter type for expanded function ((x$1) => plus2(20, x$1))
val anon2 = plus2(20,_)
^
Run Code Online (Sandbox Code Playgroud)
嗯,奇怪!我似乎无法使用单个参数列表进行部分应用.但是如果我声明第二个参数的类型,我可以部分应用!
scala> val anon2 = plus2(20,_: Int)
anon2: (Int) => Int = <function1>
scala> anon2(24)
res2: Int = 44
Run Code Online (Sandbox Code Playgroud)
编辑 - 我要观察的一件事是,似乎以下两个缩写是等价的,在这种情况下,这更明显的是,这不是"部分应用程序",而更像是"函数指针"
val anon1 = plus2(_,_)
val anon2 = plus2 _
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5386 次 |
最近记录: |