您可以观察符号操作:
$ scala -Yshow-syms -uniqid -Dscala.repl.maxprintstring=8000
在 REPL 中,请注意,您将看到包装代码的一组输出,然后是打印结果的代码位的第二组输出。
scala> def m1: String => String = s => s
[[symbol layout at end of parser]]
* package scala#22 (final)
[[symbol layout at end of namer]]
* object $read#58183
* package $line6#58181 (final)
package scala#22 (final)
[[symbol layout at end of packageobjects]]
object $read#58183
package $line6#58181 (final)
package scala#22 (final)
[[symbol layout at end of typer]]
* class String#643 (final)
* constructor Object#3505
* object $read#58184
* constructor $read#58188
* object $iw#58190
* constructor $iw#58192
* object $iw#58193
* object $iw#58194
* constructor $iw#58196
* method m1#58197
* value $anonfun#58199 (<synthetic>)
* value s#58200
...大量的剪辑...
object $iw#58194
constructor $iw#58196
method m1#58197
<$anon: Function1#2093> (final <synthetic>)
constructor $anonfun#58218
[[symbol layout at end of lambdalift]]
……剪……
object $iw#58194
O <$anon: Function1#2093> [Owner was method m1#58197, now object $iw#58194] (final <synthetic>)
constructor $anonfun$m1$1#58218
正如输出所说,anonfun 成为封闭类的子类,因为它是作为类实现的;任何捕获的变量都会传递给它的构造函数。
快速浏览LambdaLift.scala
显示,newName
实际上是由 methods 拥有的特殊情况的匿名函数,具有您指出的名称修饰。
这是避免命名冲突的简单方法,例如:
scala> class Foo { def x = 1 to 10 map (2 * _) ; def y = 1 to 10 map (3 * _) filter (_ > 6) }
但是既然newName
无论如何都要获得一个新名称,我猜想保留方法名称是一种调试帮助。
它是一个很好的调试辅助工具吗?
编译单元中任何方法“m”中的多个匿名函数都将被命名anonfun$m$1
,依此类推;没有办法区分anonfun$m$3
属于Foo.m
或Bar.m
,除非通过检查这些类。
我会依靠 REPL 为我发现 anonfus,但目前它并不比我们聪明。