转义Scala中Java互操作性的下划线

Tra*_*own 18 java scala

假设我有一些Scala代码调用一个_用作标识符的Java库(我做了 - 这是一个很长的故事).这是一个简化的例子:

public class StupidUnderscore {
  public static String _() { return "Please give me a real name!"; }
}
Run Code Online (Sandbox Code Playgroud)

没问题,对吧?逃避吧:

scala> StupidUnderscore.`_`
res0: String = Please give me a real name!
Run Code Online (Sandbox Code Playgroud)

这一直有效,直到我今天早上尝试更新到Scala 2.10.2:

scala> StupidUnderscore.`_`
<console>:1: error: wildcard invalid as backquoted identifier
       StupidUnderscore.`_`
                        ^
Run Code Online (Sandbox Code Playgroud)

这是由于2.10.1中出现的更改并修复了此问题.从提交消息:

禁止_作为标识符,它只能带来不良.

嗯,当然,但我不知道为什么这意味着我无法摆脱它 - 我认为这是反引号的意思.

我是否必须编写Java包装器才能使其工作?还有其他方法可以_在Scala中引用Java库的方法吗?


作为脚注,我已经确认可以在不编写任何新Java的情况下解决此问题:

object AwfulMacroHack {
  import scala.language.experimental.macros
  import scala.reflect.macros.Context

  def _impl(c: Context) = {
    import c.universe._
    c.Expr[String](
      Select(Ident(newTermName("StupidUnderscore")), newTermName("_"))
    )
  }

  def `I'm not named _!` = macro _impl
}
Run Code Online (Sandbox Code Playgroud)

然后:

scala> AwfulMacroHack.`I'm not named _!`
res0: String = Please give me a real name!
Run Code Online (Sandbox Code Playgroud)

不过,我不确定这比Java助手解决方案更糟糕.

Dao*_*Wen 1

由于反引号是Java 标识符互操作的机制(例如Thread.yield(),我怀疑是否还有另一种不使用反射的方法。我想说你最好的选择(直到 bug 被修复)是用 Java 编写一个静态帮助器方法来访问_.

我知道这完全是荒谬的,但它可能仍然比使用反射更好。他们用那个补丁破坏了 Java 互操作性,所以他们最终必须解决这个问题。然而,在他们这样做之前,我认为它已经被打破了。