2012-04-29 39 views
32

Có thể bỏ qua một trường của một lớp chữ hoa trong phương thức equals/haschode của lớp case?Scala: Bỏ qua trường lớp trường hợp cho bằng/hascode?

Trường hợp sử dụng của tôi là tôi có một trường cơ bản là siêu dữ liệu cho phần còn lại của dữ liệu trong lớp.

+1

Nếu bạn ghi đè lên hashcode/bằng? –

Trả lời

74

Chỉ các thông số trong phần thông số đầu tiên được xem xét cho bình đẳng và băm.

scala> case class Foo(a: Int)(b: Int) 
defined class Foo 

scala> Foo(0)(0) == Foo(0)(1) 
res0: Boolean = true 

scala> Seq(0, 1).map(Foo(0)(_).hashCode) 
res1: Seq[Int] = List(-1669410282, -1669410282) 

CẬP NHẬT

Để vạch trần b như một lĩnh vực:

scala> case class Foo(a: Int)(val b: Int) 
defined class Foo 

scala> Foo(0)(1).b 
res3: Int = 1 
+1

Nhưng 'Foo (0) (0) .b' không hoạt động. Nó cho lỗi 'value b không phải là thành viên của Foo'. –

+1

+1, tuyệt! Không biết về điều này. – missingfaktor

+2

@KenBloom nếu bạn thêm "val" trước "b" nó sẽ hoạt động: trường hợp lớp Foo (a: Int) (val b: Int) – czajah

5
scala> :paste 
// Entering paste mode (ctrl-D to finish) 

case class Foo private(x: Int, y: Int) { 
    def fieldToIgnore: Int = 0 
} 

object Foo { 
    def apply(x: Int, y: Int, f: Int): Foo = new Foo(x, y) { 
    override lazy val fieldToIgnore: Int = f 
    } 
} 

// Exiting paste mode, now interpreting. 

defined class Foo 
defined module Foo 

scala> val f1 = Foo(2, 3, 11) 
f1: Foo = Foo(2,3) 

scala> val f2 = Foo(2, 3, 5) 
f2: Foo = Foo(2,3) 

scala> f1 == f2 
res45: Boolean = true 

scala> f1.## == f2.## 
res46: Boolean = true 

Bạn có thể ghi đè .toString nếu cần.

2

Bạn có thể ghi đè lên equals và phương pháp hasCode trong một lớp học trường hợp

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

case class Person(val name:String, val addr:String) { 
    override def equals(arg:Any) = arg match { 
    case Person(s, _) => s == name 
    case _ => false 
    } 
    override def hashCode() = name.hashCode 
} 

// Exiting paste mode, now interpreting. 

scala> Person("Andy", "") == Person("Andy", "XXX") 
res2: Boolean = true 

scala> Person("Andy", "") == Person("Bob", "XXX") 
res3: Boolean = false 
+1

Không phải là một lựa chọn rất hấp dẫn vì ['.equals' là khó để có được quyền] (http://www.artima.com/lejava/articles/equality.html) và '.equals' và' .hashCode' cùng nhau tạo ra nhiều bản mẫu. – missingfaktor

+0

đồng ý rằng bằng/hashCode overrighting là lỗi dễ bị (như trong java), chỉ cần nhìn vào mã mẫu cho một ví dụ. Tuy nhiên, tất cả các phương thức khác, áp dụng/unapply/toString/etc sẽ tự động được tạo và sẽ hoạt động như trước. – andy

+0

Tôi muốn nói rằng thật dễ dàng để có được sai, chứ không phải là khó để có được quyền, nếu điều đó làm cho bất kỳ ý nghĩa :) Đã cập nhật cho một cái gì đó chính xác hơn –

0

Nếu bạn ghi đè toString trong lớp cơ sở sẽ không bị ghi đè bởi các lớp chữ hoa có nguồn gốc. Dưới đây là một ví dụ:

sealed abstract class C { 
    val x: Int 
    override def equals(other: Any) = true 
} 

case class X(override val x: Int) extends C 

case class Y(override val x: Int, y: Int) extends C 

Thần chúng tôi bạn kiểm tra:

scala> X(3) == X(4) 
res2: Boolean = true 

scala> X(3) == X(3) 
res3: Boolean = true 

scala> X(3) == Y(2,5) 
res4: Boolean = true 
Các vấn đề liên quan