/ Има ли Scala синтаксис за обновяване на записа за създаване на модифицирани клонове на неизменни структури от данни? - скала, неизменност

Има ли Скала запис на синтаксиса за обновяване на модифицирани клонинги на непостоянни структури от данни? - скала, непостоянство

В Меркурий мога да използвам:

A = B^some_field := SomeValue

да свържете А с копие на В, освен това some_field е SomeValue вместо каквото и да е в Б. Вярвам, че еквивалентът на Хаскел е нещо като:

a = b { some_field = some_value }

Дали Скала има нещо подобно"модифициране" на неизменяеми стойности. Алтернативата изглежда е да има конструктор, който директно задава всяко поле в инстанцията, което не е винаги идеално (ако има инварианти, които конструкторът трябва да поддържа). изрично предавайте всяка друга стойност в случая, който искам да имам модифицирано копие на.

Не можех да намеря нищо за това с помощта на Google,или в кратък преглед на езиковия справочник или "Scala By Example" (който съм прочел от начало до край, но не съм усвоил все още, така че може и да е там).

Виждам, че тази функция може да има някои странни взаимодействия със защитата на достъпа до Java стила и подкласовете, въпреки че ...

Отговори:

11 за отговор № 1

Можете да използвате класове случаи за това, но не е нужно. Класовете случаи не са нищо магическо - модификаторът case просто ви спестява много пишете. Методът на копиране се реализира чрез използването на имена и параметри по подразбиране. Имената са същите като полетата и по подразбиране са текущите стойности на полетата. Ето пример:

class ClassWithCopy(val field1:String, val field2:Int) {
def copy(field1:String = this.field1, field2:Int = this.field2) = {
new ClassWithCopy(field1,field2);
}
}

Можете да използвате това точно като метода на копиране на класове случаи. Имената и параметрите по подразбиране са много полезна функция, а не само за копиране.


26 за отговор № 2

Ако дефинирате класа си като case class, удобно copy Генериран е методът, който ви позволява да зададете с име параметри нови стойности за определени полета.

scala> case class Sample(str: String, int: Int)
defined class Sample

scala> val s = Sample("text", 42)
s: Sample = Sample(text,42)

scala> val s2 = s.copy(str = "newText")
s2: Sample = Sample(newText,42)

Той дори работи с полиморфни класове:

scala> case class Sample[T](t: T, int: Int)
defined class Sample

scala> val s = Sample("text", 42)
s: Sample[java.lang.String] = Sample(text,42)

scala> val s2 = s.copy(t = List(1,2,3), 42)
s2: Sample[List[Int]] = Sample(List(1, 2, 3),42)

Забележи, че s2 има различен тип от s.


4 за отговор № 3

Ако обектът, който планирате да модифицирате, е клас на случай, можете да използвате метода за автоматично генерирано копие:

scala> val user = User(2, "Sen")
user: User = User(2,Sen)

scala> val corrected = user.copy(name = "Sean")
corrected: User = User(2,Sean)