Oba wspomniane sposoby należą odpowiednio do paradygmatów funkcjonalnych i OO. Jeśli wolisz rozkład funkcjonalny z abstrakcyjnym typem danych, który w Scali jest reprezentowany przez klasy przypadków, wybierz metodę kopiowania. Używanie mutatorów nie jest dobrą praktyką w mojej opcji, ponieważ spowoduje to powrót do stylu życia Java/C#/C++.
Z drugiej strony podejmowania ADT klasę case jak
case class Person(name: String, age: String)
jest bardziej zwarte wtedy:
class Person(_name: String, _age: String) {
var name = _name
var age = _a
def changeName(newName: String): Unit = { name = newName }
// ... and so on
}
(nie najlepszy kod imperatyw, może być krótsza, ale jasne).
Przyczyny istnieje inny sposób z mutatorów, żeby powrócić nowy obiekt na każdej rozmowy:
class Person(val name: String,
val age: String) {
def changeName(newName: String): Unit = new Person(newName, age)
// ... and so on
}
Ale nadal klasa przypadek sposobem jest bardziej zwarte.
A jeśli pójdziecie dalej, do programowania równoległego/równoległego, zobaczycie, że funkcjonalna koncepcja z niezmienną wartością jest o wiele lepsza, a następnie próbuje odgadnąć, w jakim stanie obecnie znajduje się obiekt.
Aktualizacja
Dzięki Senia, zapomniałem wspomnieć o dwóch rzeczach.
Soczewki
Na najbardziej podstawowym poziomie, soczewki są rodzajem pobierające i ustawiające dla danych niezmiennych i wygląda następująco:
case class Lens[A,B](get: A => B, set: (A,B) => A) {
def apply(a: A) = get(a)
// ...
}
To jest to. Obiektyw jest obiektem, który zawiera dwie funkcje: get i set. get pobiera A i zwraca zestaw B. pobiera A i B i zwraca nowy A. Łatwo zauważyć, że typ B jest wartością zawartą w A. Kiedy przekazujemy instancję, aby uzyskać, zwracamy tę wartość. Kiedy przekazujemy A i B do ustawienia, aktualizujemy wartość B w A i zwracamy nowe A odzwierciedlające zmianę. Dla wygody uzyskuje się aliasy do zastosowania.Jest dobry intro do Scalaz Lens Case klasy
Records
Ten jeden, ofcause, pochodzi z biblioteki shapeless i nazwał Records. Implementacja rozszerzalnych rekordów modelowanych jako HLists stowarzyszeń. Klawisze są kodowane za pomocą singleton rodzajów iw pełni określić rodzaje odpowiadających im wartości (ex od github):
object author extends Field[String]
object title extends Field[String]
object price extends Field[Double]
object inPrint extends Field[Boolean]
val book =
(author -> "Benjamin Pierce") ::
(title -> "Types and Programming Languages") ::
(price -> 44.11) ::
HNil
// Read price field
val currentPrice = book.get(price) // Inferred type is Double
currentPrice == 44.11
// Update price field, relying on static type of currentPrice
val updated = book + (price -> (currentPrice+2.0))
// Add a new field
val extended = updated + (inPrint -> true)
aby zmiany, można użyć Event Sourcing. –