Không có mâu thuẫn: class A(x: => Int)
tương đương với class A(private[this] val x: => Int)
và không class A(private val x: => Int)
. private[this]
đánh dấu một cá thể có giá trị riêng tư, trong khi một trình sửa đổi riêng mà không có đặc tả kỹ hơn cho phép truy cập vào giá trị từ bất kỳ cá thể nào của lớp đó.
Thật không may, việc xác định case class A(private[this] val x: => Int)
cũng không được phép. Tôi cho rằng đó là vì các kiểu chữ thường cần truy cập vào các giá trị của các hàm tạo khác của các cá thể khác, vì chúng thực hiện phương thức equals
.
Tuy nhiên, bạn có thể thực hiện các tính năng mà một lớp trường hợp sẽ cung cấp bằng tay:
abstract class MyList[+T]
class MyNode[T](val h: T, t: => MyList[T]) extends MyList[T]{
def getT = t // we need to be able to access t
/* EDIT: Actually, this will also lead to an infinite recursion
override def equals(other: Any): Boolean = other match{
case MyNode(i, y) if (getT == y) && (h == i) => true
case _ => false
}*/
override def hashCode = h.hashCode
override def toString = "MyNode[" + h + "]"
}
object MyNode {
def apply[T](h: T, t: => MyList[T]) = new MyNode(h, t)
def unapply[T](n: MyNode[T]) = Some(n.h -> n.getT)
}
Để kiểm tra mã này, bạn có thể thử:
def main(args: Array[String]): Unit = {
lazy val first: MyNode[String] = MyNode("hello", second)
lazy val second: MyNode[String] = MyNode("world", first)
println(first)
println(second)
first match {
case MyNode("hello", s) => println("the second node is " + s)
case _ => println("false")
}
}
Thật không may, tôi không biết chắc chắn tại sao các thành viên val và var gọi theo tên đều bị cấm. Tuy nhiên, có ít nhất một mối nguy hiểm cho nó: Hãy suy nghĩ về cách các trường hợp lớp học thực hiện toString
; Giá trị toString
của mọi giá trị hàm tạo được gọi. Điều này có thể (và trong ví dụ này sẽ) dẫn đến các giá trị tự gọi là vô hạn. Bạn có thể kiểm tra điều này bằng cách thêm t.toString
đến 's toString
-method.
Edit: Sau khi đọc comment Chris Martin: Việc thực hiện equals
cũng sẽ đặt ra một vấn đề mà có lẽ là nghiêm trọng hơn việc thực hiện các toString
(mà chủ yếu được sử dụng để gỡ lỗi) và hashCode
(mà sẽ chỉ dẫn đến cao tỷ lệ va chạm nếu bạn không thể đưa thông số vào tài khoản). Bạn phải suy nghĩ cẩn thận về cách bạn sẽ triển khai equals
để có ý nghĩa.
Nguồn
2014-11-05 04:59:04
Đối với cấu trúc dữ liệu vô hạn, đường trường hợp cung cấp giá trị bao nhiêu? 'equals',' hashCode', 'toString' sẽ không hoạt động. Và tôi không chắc những gì tôi mong đợi từ 'unapply'. –