Escaping underscore for Java interoperability in S

2020-04-02 03:22发布

问题:

Suppose I've got some Scala code that calls a Java library that uses _ as an identifier (and I do—it's a long story). Here's a simplified example:

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

No problem, right? Just escape it:

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

And this has always worked, until I tried to update to Scala 2.10.2 this morning:

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

This is due to a change that showed up in 2.10.1 and fixes this issue. From the commit message:

Prohibit _ as an identifier, it can only bring badness.

Well, sure, but I don't know why that means I can't escape it—I thought that's what backquotes were for.

Am I going to have to write a Java wrapper to get this to work? Is there some other way I can refer to a Java library's _ method in Scala?


As a footnote, I've confirmed that it's possible to work around this issue without writing any new 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
}

And then:

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

I'm not sure this is any less horrible than the Java helper solution, though.

回答1:

Since backticks are the mechanism for Java interop on identifiers (e.g. Thread.yield()), I doubt there's another way without using Reflection. I'd say your best bet (until the bug is fixed) is to write a static helper method in Java to access the _.

I know this is totally ridiculous, but it's probably still better than using reflection. They broke Java interop with that patch, so they'll have to address this issue eventually. Until they do, however, I think it's just broken.



标签: java scala