2011-06-10 64 views
3

我剛開始玩Scala,並一直使用Michel Schinz的「Scala By Example」(http://www.scala-lang.org/node/198)作爲起點。在特質部分,我試圖使用反射/方法調用來測試特性,並想測試所有的比較運算符。我遇到了這個問題,並在NameTransformer中爲操作員找到了解決方案。但是,!=運算符在我看來並不會轉換爲等效函數,如<,< =,>,> = =等於。我想知道是否有辦法調用!=很像其他我沒有發現的操作符?如何在對象上調用'!='方法?

從PDF:

trait ord { 
def < (that:Any):Boolean 
def <= (that:Any):Boolean = (this < that) || (this == that) 
def > (that:Any):Boolean = !(this <= that) 
def >= (that:Any):Boolean = !(this < that) 
} 

class Date(y:Int, m:Int, d:Int) extends ord{ 
def year = y 
def month = m 
def day = d 

override def toString():String = year + "-" + month + "-" + day 

override def equals(that:Any): Boolean = 
    that.isInstanceOf[Date] && { 
    val o = that.asInstanceOf[Date] 
    o.day == this.day && o.month == this.month && o.year == this.year 
    } 

override def <(that:Any):Boolean = { 
    if (!that.isInstanceOf[Date]) 
    error("Cannot compare " + that + " and date") 
    val o = that.asInstanceOf[Date] 
    (year < o.year) || 
    (year == o.year && (month < o.month || 
    (month == o.month && day < o.day))) 
} 
} 

我的代碼:

def Classes_Traits(){ 
val (d1, d2, d3) = (new Date(2001, 10, 1), new Date(2001, 10, 1), new Date(2000, 1, 10)) 
println("d1 : " + d1) 
println("d2 : " + d2) 
println("d3 : " + d3) 


Array((d1,d2), (d2,d3), (d3,d1)).foreach { 
    (comp:(Date, Date)) => 
    println("comparing " + comp._1 + " and " + comp._2) 
    val d = comp._1.getClass() 
    Map(
     "equals   " -> "equals", 
     "not equals  " -> "!=", 
     "less than   " -> "<", 
     "less than or equal" -> "<=", 
     "more than   " -> ">", 
     "more than or equal" -> ">=").foreach { 
    (a) => 
     println(a._1 + " : " + 
     d.getMethod(scala.reflect.NameTransformer.encode(a._2), 
        classOf[Object]).invoke(comp._1, comp._2)) 
     } 
    /*println("equals : " + m.invoke(comp._1, comp._2)) 
    // Same as above 
    println(comp._1 + " == " + comp._2 + " is " + (comp._1 == comp._2)) 
    println(comp._1 + " != " + comp._2 + " is " + (comp._1 != comp._2)) 
    println(comp._1 + " > " + comp._2 + " is " + (comp._1 > comp._2)) 
    println(comp._1 + " >= " + comp._2 + " is " + (comp._1 >= comp._2)) 
    println(comp._1 + " < " + comp._2 + " is " + (comp._1 < comp._2)) 
    println(comp._1 + " <= " + comp._2 + " is " + (comp._1 <= comp._2)) 
    */ 
    } 
} 

例外: 比較2001年10月1日和2001年10月1日 大於或等於:真比 更多:假

Exception in thread "main" java.lang.NoSuchMethodException: proj2.Main$Date.$bang$eq(java.lang.Object) 
    at java.lang.Class.getMethod(Class.java:1605) 
    at proj2.Main$$anonfun$Classes_Traits$1$$anonfun$apply$1.apply(Main.scala:180) 
    at proj2.Main$$anonfun$Classes_Traits$1$$anonfun$apply$1.apply(Main.scala:178) 
    at scala.collection.immutable.HashMap$HashMap1.foreach(HashMap.scala:125) 
    at scala.collection.immutable.HashMap$HashTrieMap.foreach(HashMap.scala:344) 
    at proj2.Main$$anonfun$Classes_Traits$1.apply(Main.scala:177) 
    at proj2.Main$$anonfun$Classes_Traits$1.apply(Main.scala:168) 
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:34) 
    at scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:35) 
    at proj2.Main$.Classes_Traits(Main.scala:167) 
    at proj2.Main$.main(Main.scala:26) 
    at proj2.Main.main(Main.scala) 

回答

5

嘗試撥打equals並否定結果。 ==!=受益於Scala中的一點編譯器魔法(例如,您可以在不獲取NullPointerException的情況下調用null.==(4))。

+0

謝謝。我將更多地關注'=='和'!='的特殊編譯器。指點在哪裏讀取它們是受歡迎的。 – 2011-06-13 15:59:41

+0

我想說,對於這些問題,編譯小片段並查看生成的字節碼是理解編譯器的最佳方式。或者,查看編譯器的源代碼... – 2011-06-13 18:54:53