Ant*_*ner 5 methods scala function
在尝试scala的eta扩展后,我遇到了一个奇怪的功能.让我们定义一个方法:
scala> def sum(a: Int, b: Int): Int = a + b
sum: (a: Int, b: Int)Int
Run Code Online (Sandbox Code Playgroud)
好的,到现在为止,一切都很好.现在让我们使用eta扩展将其分配给val:
scala> val f = sum _
f: (Int, Int) => Int = $$Lambda$1051/694580932@55638165
Run Code Online (Sandbox Code Playgroud)
现在,奇怪的事情即将到来.我可以再次将eta扩展应用于f,并且它正在工作(但它会为我的方法添加currying):
scala> val g = f _
g: () => (Int, Int) => Int = $$Lambda$1055/1351568309@5602e540
Run Code Online (Sandbox Code Playgroud)
这为什么有效?我认为eta扩展只适用于方法.而且,我注意到这是不可能的:
scala> ((a: Int, b: Int) => a + b: Int) _
<console>:12: error: _ must follow method; cannot follow (Int, Int) => Int
((a: Int, b: Int) => a + b: Int) _
^
Run Code Online (Sandbox Code Playgroud)
但是将eta扩展应用到f是不一样的?我有点困惑,这些eta扩展仍然为我隐藏了一些魔力.非常感谢 !
当您val f = sum _在REPL或对象/类的顶级写入时,Scala定义了一个访问器方法,以便您可以访问它.这里是斯卡拉如何desugars这(通过scalac -Xprint:typer上val f: (Int, Int) => Int = _ + _):
private[this] val f: (Int, Int) => Int = ((x$1: Int, x$2: Int) => x$1.+(x$2));
<stable> <accessor> def f: (Int, Int) => Int = Foo.this.f;
Run Code Online (Sandbox Code Playgroud)
因此,当您随后编写时val g = f _,它正在对零参数访问器方法进行eta扩展,从而导致您看到的行为.有关此问题的更多验证,请注意,如果将定义放在方法中,则会出现错误:
def foo = {
val f: (Int, Int) => Int = _ + _
val g = f _ // error: _ must follow method; cannot follow (Int, Int) => Int
}
Run Code Online (Sandbox Code Playgroud)
这是因为只为字段(和顶级REPL定义生成访问器,这些定义被视为字段).
| 归档时间: |
|
| 查看次数: |
134 次 |
| 最近记录: |