множественная непереносимость, наборы и переопределение hashCode / equals - PullRequest
0 голосов
/ 03 мая 2011

Код ниже генерирует:
Имя хэш-кода
Имя хэш-кода
Имя равно
ID = 0

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
  }
}

Поскольку "people" - это набор PersonID, я ожидал следующий вывод:
Хеш-код PersonID
Хеш-код PersonID
ID = 0
ID = 1

Может ли кто-нибудь объяснить это поведение и как сделать то, что я ожидал (то есть иметь класс с "равно", основанный на значениях полей, кроме случаев помещения экземпляра в Set [PersonID])

Еще одна загадка - почему я получаю бесконечные циклы, когда использую super.hashCode () в моем собственном hashCode?

PS: я использую предварительно инициализированный абстрактный член, потому что он мне нужен в моем реальном случае ...

Ответы [ 2 ]

1 голос
/ 03 мая 2011

Другая загадка заключается в том, почему я получаю бесконечные циклы, когда использую super.hashCode () в своем пользовательском hashCode?

За пределами чисел в штучной упаковке вся реализация ## заключается в вызовеhashCode.

В вашей реализации hashCode вы звоните (или пытаетесь позвонить) ##.

Загадка раскрыта!

1 голос
/ 03 мая 2011

Вместо этого я получаю:

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

Это происходит потому, что Name - последняя черта в инициализации, поэтому ее переопределения hashCode и equals будут вызываться первыми.Вы хотели, чтобы Set вызывал методы, основанные на статическом типе (т. Е. На том, что было объявлено), а это не совсем так, как работает ОО.Если бы это было правдой, наследование и переопределение было бы практически бесполезным.

Что касается того, как выполнить то, что вы хотите ... вы не можете.Было бы неплохо, если бы был Set, который принимал класс типа Equal[A], но это не так.Может быть, это есть у Скалаза.

Кстати, есть звонок на super.##, который на Scala 2.9.0.rc2 считается незаконным.Я еще не уверен, что это значит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...