您可以观察符号操作:
$ 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 实际上是special-cases anonymous functions that are owned by 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 为我发现 anonfun,但目前它并不比我们聪明。