Tôi đã đọc rằng Scala'a case class
xây dựng tự động tạo ra một phù hợp equals
và hashCode
thực hiện. Mã được tạo chính xác trông như thế nào?hashCode trong trường hợp các lớp học trong Scala
Trả lời
Như giáo sư của tôi thường nói, chỉ có đoạn mã mới nói lên sự thật! Vì vậy, chỉ có một cái nhìn vào mã được tạo ra cho:
case class A(i: Int, s: String)
Chúng tôi có thể hướng dẫn các trình biên dịch Scala để hiển thị chúng tôi mã tạo ra sau khi các giai đoạn khác nhau, ở đây sau khi typechecker:
% scalac -Xprint:typer test.scala
[[syntax trees at end of typer]]// Scala source: test.scala
package <empty> {
@serializable case class A extends java.lang.Object with ScalaObject with Product {
..
override def hashCode(): Int = ScalaRunTime.this._hashCode(A.this);
...
override def equals(x$1: Any): Boolean = A.this.eq(x$1).||(x$1 match {
case (i: Int,s: String)A((i$1 @ _), (s$1 @ _)) if i$1.==(i).&&(s$1.==(s)) => x$1.asInstanceOf[A].canEqual(A.this)
case _ => false
});
override def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[A]()
};
}
Vì vậy, bạn có thể thấy rằng việc tính toán mã băm được phân bổ cho ScalaRunTime._hashCode và sự bình đẳng phụ thuộc vào sự bình đẳng của các thành viên của nhóm trường hợp.
Điều này không chỉ giải thích tốt, mà còn dạy tôi về '-Xprint: typer'. Cảm ơn rất nhiều! Điều duy nhất tôi đang bối rối là 'ScalaRunTime.this' có nghĩa là gì? Tại sao không chỉ đơn giản là 'ScalaRunTime._hashCode'? –
Cú pháp 'ClassName.this' thường được sử dụng để truy cập một' this' bên ngoài từ bên trong một lớp bên trong (giống như trong Java). Không chắc chắn tại sao nó được in ở đây, có lẽ nó chỉ là cách mã được in khá bởi trình biên dịch. Nhưng đó chỉ là một đoán, bất cứ ai khác? –
Các tạo hashCode
chỉ gọi scala.runtime.ScalaRunTime._hashCode
, được định nghĩa là:
def _hashCode(x: Product): Int = {
val arr = x.productArity
var code = arr
var i = 0
while (i < arr) {
val elem = x.productElement(i)
code = code * 41 + (if (elem == null) 0 else elem.hashCode())
i += 1
}
code
}
Vì vậy, những gì bạn nhận được là elem1 * 41**n + elem2 * 41**(n-1) .. elemn * 1
, nơi n
là arity của lớp trường hợp của bạn và elemi
là những thành viên trong đó trường hợp lớp.
Cảm ơn câu trả lời rõ ràng. Bây giờ tôi không biết liệu tôi có nên chấp nhận câu trả lời của bạn hay câu trả lời của Mirko hay không, từ đó tôi cũng đã học được các mẹo '-Xprint: typer' tiện dụng ... –
Cùng với nhau, cả hai câu trả lời đều hoàn toàn trả lời câu hỏi :-) –
Xin lưu ý rằng các câu trả lời trước đây về câu hỏi này hơi lỗi thời trên phần hashCode.
Kể từ scala 2.9 hashCode
đối với các trường hợp sử dụng MurmurHash
: link.
MurmurHash produces good avalanche effect, good distribution and is CPU friendly.
Dường như mọi thứ đã thay đổi; sử dụng của Mirko dụ case class A(i: Int, s: String)
tôi nhận được: [? đang gì được tạo ra cho một phương pháp bình đẳng/hashCode của một lớp hợp]
override <synthetic> def hashCode(): Int = {
<synthetic> var acc: Int = -889275714;
acc = scala.runtime.Statics.mix(acc, i);
acc = scala.runtime.Statics.mix(acc, scala.runtime.Statics.anyHash(s));
scala.runtime.Statics.finalizeHash(acc, 2)
};
và
override <synthetic> def equals(x$1: Any): Boolean = A.this.eq(x$1.asInstanceOf[Object]).||(x$1 match {
case (_: A) => true
case _ => false
}.&&({
<synthetic> val A$1: A = x$1.asInstanceOf[A];
A.this.i.==(A$1.i).&&(A.this.s.==(A$1.s)).&&(A$1.canEqual(A.this))
}))
};
- 1. Scala: Kết hợp các lớp trường hợp
- 2. Đối sánh nhiều trường hợp với các lớp học trong scala
- 3. trường hợp lớp học từ Bản đồ
- 4. Sử dụng trường hợp cho các lớp học chính thức
- 5. Scala: Bỏ qua trường lớp trường hợp cho bằng/hascode?
- 6. bình đẳng Overriding() & hashCode() trong các lớp học phụ ... xem xét siêu lĩnh vực
- 7. Làm cách nào để tách các Lớp Trường hợp có các Tùy chọn trong Scala
- 8. Trường hợp không nên sử dụng các trường hợp ở Scala?
- 9. quá tải phương pháp unapply trong trường hợp các lớp: scala
- 10. Lớp học Case với các lĩnh vực tùy chọn trong Scala
- 11. Java bằng() và hashCode() dựa trên các trường khác nhau?
- 12. dùng mới với Scala thức trường hợp lớp
- 13. Các trường bit trong Scala
- 14. Trừ Lớp học tổng hợp trong Emma trong STS
- 15. Trong những trường hợp này, lớp giá trị Scala sẽ được "đóng hộp", phải không?
- 16. Tạo mô hình với trường hợp Scala
- 17. vượt qua số biến của tham số trong scala (2.8) trường hợp lớp để constructor mẹ
- 18. trường hợp của lớp Class
- 19. Reflection trên một trường hợp Scala
- 20. Làm thế nào để serialize/deserialize trường hợp lớp học đến/từ Json trong Play 2.1
- 21. scala: trừu tượng lớp học instantiation?
- 22. Làm thế nào tôi có thể deserialize từ JSON với Scala sử dụng * không trường hợp * lớp học?
- 23. Làm cách nào để tôi có thể đối sánh các lớp học trong một tuyên bố "phù hợp" Scala?
- 24. Tại sao có thể kết hợp các lớp trong một trường loại?
- 25. scala đối tượng trường hợp ô nhiễm
- 26. Làm thế nào để phù hợp với mô hình một lớp lồng nhau trong Scala?
- 27. Hợp nhất các tập khổng lồ (HashSet) trong Scala
- 28. tham chiếu lớp học về phía trước ở Scala?
- 29. Scala mẫu sẽ không phù hợp với java.lang.String và trường hợp lớp
- 30. Tìm các lớp học có sẵn trong Học phần
thể trùng lặp của (http://stackoverflow.com/ câu hỏi/4526706/mã-được-tạo-cho-một-bằng-hash-phương pháp-of-a-case-class) – Suma