2011-08-09 43 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的名称。以非字母字符(非_和$)开头的名称只能包含非字母字符。

除此之外,您需要的语义可以通过隐式转换轻松完成。

相关问题