2013-07-25 33 views
18

假設我有一些調用Java庫的Scala代碼,它使用_作爲標識符(而且我這麼做 - 這是一個很長的故事)。這裏有一個簡化的例子:在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! 

而這一直工作,直到我試圖今早更新到斯卡拉2.10.2:

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

這是由於a change在2.10.1出現了,修復this issue。來自提交信息:

禁止_作爲標識符,它只能帶來壞處。

嗯,當然,但我不知道爲什麼這意味着我無法逃避它 - 我認爲這就是反引號。

我將不得不編寫一個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

它看起來像是反勾「。」是可以接受的。那裏沒有「壞」,顯然...(如果可以在SO評論中出現反撥,我不知道如何) –

+1

[每次改變都會打斷某人的工作流程](http://xkcd.com/1172 /)。你應該報告錯誤,或者重新打開舊錯誤,因爲修復不好。在我看來,他們需要修復別名代碼,不要禁止'_'作爲標識符。就像你指出的那樣,這打破了Java的iterop,這肯定比原來的問題修復處理... – DaoWen

+0

@RandallSchulz''''我得到了一個!看到這個元問題:[反斜槓轉義註釋中的代碼區域](http://meta.stackexchange.com/questions/74340/backslash-escaping-in-code-regions-in-comments) – DaoWen

回答

1

由於反引號是 Java互操作標識符(e.g. Thread.yield())的機制,我懷疑沒有使用反射的另一種方法。我會說你最好的選擇(直到錯誤得到解決)是用Java編寫一個靜態輔助方法來訪問_

我知道這完全是荒謬的,但它可能仍然比使用反射更好。他們用這個補丁打破了Java的互操作性,所以他們最終必須解決這個問題。但是,直到他們這樣做,我認爲它已經破裂。

+1

是的,這就是我所害怕的。我已經評論了這個問題,並會在我回復後重新開放。與此同時,我編輯了這個問題,增加了另一個(同樣荒謬的)臨時解決方案(它使用反射,但只是編譯時反射)。 –

+0

@TravisBrown - 我很驚訝宏解決方案的作品。我原以爲他們所做的編譯器更改也會禁止'newTermName(「_」)'。儘管它看起來有點駭人聽聞,但這可能比編寫Java類更好。也許你甚至可以使用一個隱式的值類來將'''我沒有命名_!''屬性添加到有問題的Java對象中。 – DaoWen