2011-08-09 45 views
1

考慮以下幾點:有沒有辦法在運行時重命名Scala(或Java)中的方法?

case class Num(value: Double) { 
    def plus(rhs: Num) = Num(value + rhs.value) 
    def times(rhs: Num) = Num(value * rhs.value) 
} 

object TestApp extends App { 
    // ** maybe do something here 
    val one = Num(1) 
    val two = Num(2) 
    val three = Num(3) 
    val result = three plus one times two 
} 

有沒有辦法在Numplus方法/函數重命名爲+plustimes方法*times在運行時,因爲result = three +- one *- two

這在運行時發生是非常重要的。如果可能的話,我想避免編譯器插件。另外,如果適用,我不反對java示例。

我想這樣做的原因是因爲Scala中的默認運算符優先級爲three plus one times two結果在8時three +- one *- two導致5

+0

如果您使用代數優先的結果不應該是5,這是6 –

+0

我的直覺是,這個問題是不是Scala的predecence的默認順序,而你不知道不需要重新命名方法來「解決」這個問題。 –

+2

@Amir阿富汗人,3 + 1 * 2 = 5「正常」優先規則,不知道哪裏來的6。 –

回答

6

你假設運營商的優先順序會按照你想要的方式命名,這不會奏效。我能想到的最快捷的方法,使這項工作是一個皮條客,因爲@戴夫格里菲斯建議:

case class Num(value: Double) 

object Main { 
    implicit def toDouble(v: Num) = v.value 
    implicit def toNum(v: Double) = Num(v) 
    def main(args: Array[String]) { 
    val one = Num(1) 
    val two = Num(2) 
    val three = Num(3) 
    val result: Num = three + one * two 
    println(result) 
    } 
} 

更重要的是,你不能做到這一點,在「運行」。你如何期望在編譯時調用一個名字不存在的函數?即Num.+plus其中Num沒有+plus方法?編譯器會告訴你迷路了。而且,如前所述,+plus無論如何都是無效的。

編輯:我今天又在看這個,我不確定我在抽菸。一個更好的皮條客是:

class NumMath(u: Num) { 
    def +(v: Num) = Num(u.value + v.value) 
    def *(v: Num) = Num(u.value * v.value) 
} 

object Num { 
    implicit def toNumMath(v: Num) = new NumMath(v) 
} 
case class Num(value: Double) 

object Main { 
    import Num._ 
    def main(args: Array[String]) { 
    val one = Num(1) 
    val two = Num(2) 
    val three = Num(3) 
    val result = three + one * two 
    println(result) 
    } 
} 
+0

我不同意第一句話。第一個操作符定義了優先級(參見Scala規範6.12.3)。當然,運營商標識符必須是有效的,並且'+ add'不像您指出的那樣有效。但是'* - <<'是有效的,並且比' - << *' – paradigmatic

+0

更高的優先級。 :)感謝您指出。我很快就要閱讀這個規範。 –

+0

我們假設運營商標識符是有效的。我們將如何做到這一點? – mepcotterell

3

+plus*times不是有效的Scala的名稱。以非字母字符(非_和$)開頭的名稱只能包含非字母字符。

除此之外,您需要的語義可以通過隱式轉換輕鬆完成。

相關問題