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

2022-09-02 22:43:32

假设我有一些 Scala 代码调用了一个用作标识符的 Java 库(我确实这样做了——这是一个很长的故事)。下面是一个简化的示例:_

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

没问题,对吧?只需逃离它:

scala> StupidUnderscore.`_`
res0: String = Please give me a real name!

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

scala> StupidUnderscore.`_`
<console>:1: error: wildcard invalid as backquoted identifier
       StupidUnderscore.`_`
                        ^

这是由于 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
}

然后:

scala> AwfulMacroHack.`I'm not named _!`
res0: String = Please give me a real name!

不过,我不确定这是否比Java帮助程序解决方案更可怕。


答案 1

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

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


答案 2

推荐