В Меркурий мога да използвам:
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)