2011-05-02 43 views
0

下面的代碼生成:
名稱的的hashCode
名稱的的hashCode
名稱的等於
ID = 0多個inherance,套裝和hashCode /等於首要

import scala.collection.mutable 
object TestTraits { 
    def main(args: Array[String]): Unit = { 
    val toto0 = new Person(0,"toto") 
    val toto1 = new Person(1,"toto") 
    val peoples = mutable.Set.empty[PersonID] 
    peoples.add(toto0) 
    peoples.add(toto1) 
    peoples.foreach(_.showID) 
    //peoples.foreach(_.saySomething)//won't compile' 
    } 
} 

trait Name{ 
    var theName="" 
    override def hashCode(): Int = { 
    println("Name's hashCode") 
    var hash = 5; 
    hash = 71 * hash + this.theName.##; 
    hash 
    //super.hashCode()//infinite loop 
    } 

    override def equals(that: Any): Boolean = { 
    println("Name's equals") 
    that match { 
    case that: Name  => this.theName.equals(that.theName) 
    case _ => false 
    } 
    } 
} 

abstract class PersonID{ 
    val idNumber: Int 

    override def hashCode(): Int = { 
    println("PersonID's hashCode") 
    super.## 
    } 
    override def equals(that: Any): Boolean = { 
    println("PersonID's equals") 
    that match { 
    case that: PersonID  => this.eq(that) 
    case _ => false 
    } 
    } 
    def showID: Unit = { 
    println("ID=" + idNumber) 
    } 
} 

class Person(val id:Int, val s:String) extends { 
    val idNumber=id 
} with PersonID with Name { 
    /*override def hashCode(): Int = { 
    println("Person's hashCode") 
    super.## //infinite loop !! 
    } 
    override def equals(that: Any): Boolean = { 
    println("Person's equals") 
    that match { 
    case that: Person  => this.eq(that) 
    case _ => false 
    } 
    }*/ 
    theName=s 
    def saySomething: Unit = { 
    print("Hello, my name is " + theName + ", ") 
    showID 
    } 
} 

由於 「人民」 是一組是PersonID的,我期待以下輸出:
PersonID的hashCode
PersonID的hashCode
ID = 0
ID = 1

有人可以解釋這種行爲,以及如何做我期望的(也就是說,有一個基於字段的值的「等於」的類除了將實例放入Set [PersonID] )

另一個謎就是爲什麼當我在自定義hashCode中使用super.hashCode()時會出現無限循環?

PS:我用一個預先初始化的抽象成員,因爲我需要它在我的實際使用情況......

回答

1

我得到這個代替:

Name's hashCode 
Name's hashCode 
Name's equals 
ID=0 

這是因爲Name是在最後的特質初始化,所以它的覆蓋hashCodeequals將是第一個被調用。你想要Set基於靜態類型(即已聲明的)調用方法,這不僅僅是OO的工作方式。如果那是真的,繼承和重寫將幾乎毫無用處。

至於如何實現你想要的......你不能。如果有一個Set需要Equal[A]類型的類,但是沒有。也許斯卡拉茲擁有它。

順便說一句,有一個super.##這是在Scala 2.9.0.rc2上被認爲是非法的。我不確定那是什麼意思。

+0

感謝您的回答,現在很明顯,我必須以不同的方式實施。 – acapola 2011-05-04 10:46:18

1

另一個謎就是爲什麼當我在自定義hashCode中使用super.hashCode()時會出現無限循環?

在盒裝數字之外,##的整個實現是調用hashCode。

在你實現hashCode時,你正在調用(或試圖調用)##。

神祕解決!

+0

我認爲不應該發生遞歸,因爲我打算調用super.hashCode(),而不是this.hashCode()。和你一樣,我一直認爲hashCode和##實際上是相同的方法,但是在通過hashCode()更改##之後,無限循環消失... – acapola 2011-05-04 10:53:21

+0

我很確定它是如何工作的,因爲我寫了它。 ##調用hashCode。我不確定哪部分內容不清楚,或者我會進一步闡述。 – extempore 2011-05-05 06:01:48

+0

不清楚的是,儘管調用super,我仍然無限循環。 scala論壇上的另一個人給了我下面的解釋:「你的無限循環是由在hashCode方法定義中使用super. ##引起的。調用x. ##將轉化爲調用ScalaRunTime。hash(x)反過來爲AnyRef的後代,將調用x.hashCode()。在這裏使用超級沒有幫助你。如果你使用super.hashCode(),那麼你會得到你期望的行爲。「 – acapola 2011-05-07 13:31:10