Nie ma sprzeczności: class A(x: => Int)
jest równoważna class A(private[this] val x: => Int)
i nie class A(private val x: => Int)
. private[this]
oznacza wartość instancji-private, a modyfikator prywatny bez dalszych specyfikacji umożliwia uzyskanie dostępu do wartości z dowolnej instancji tej klasy.
Niestety, zdefiniowanie case class A(private[this] val x: => Int)
jest niedozwolone. Zakładam, że tak jest, ponieważ klasy przypadków potrzebują dostępu do wartości konstruktora innych instancji, ponieważ implementują metodę equals
.
Niemniej jednak, można realizować funkcje klasa przypadek nadadzą ręcznie:
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)
}
Aby sprawdzić ten kod, można spróbować:
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")
}
}
Niestety, nie wiem na pewno, dlaczego nazwani członkowie val i var są zabronieni. Istnieje jednak co najmniej jedno zagrożenie: pomyśl o tym, w jaki sposób klasy przypadków implementują toString
; Metoda toString
- metoda każdej wartości konstruktora jest wywoływana. Mogłoby to (iw tym przykładzie) prowadzić do wartości, które nazywają się nieskończenie. Można to sprawdzić, dodając metodę t.toString
do MyNode
za pomocą metody toString
.
Edit: Po przeczytaniu komentarza Chris Martin: Realizacja equals
będzie również stanowić problem, który jest prawdopodobnie bardziej dotkliwe niż realizacja toString
(który jest stosowany głównie do debugowania) i hashCode
(która doprowadzi jedynie do wyżej współczynniki kolizji, jeśli nie można wziąć parametru pod uwagę). Musisz uważnie przemyśleć, jak zaimplementować equals
, aby było sensowne.
Dla nieskończonej struktury danych, jaką wartość zapewnia cukier klasy przypadku? 'equals',' hashCode', 'toString' nie będzie działać. I nie jestem pewien, czego bym się spodziewał po "unapply". –