2011-07-12 10 views
15

Mercury mogę użyć:Czy Scala ma składnię aktualizacji rekordów do tworzenia zmodyfikowanych klonów niezmiennych struktur danych?

A = B^some_field := SomeValue 

powiązać do kopii B, oprócz tego, że jest SomeValuesome_field zamiast cokolwiek to było w B. Uważam, że ekwiwalent Haskell jest coś takiego:

a = b { some_field = some_value } 

Czy Scala ma coś takiego do "modyfikowania" niezmiennych wartości. Alternatywą wydaje się być konstruktor, który bezpośrednio ustawia każde pole w instancji, co nie zawsze jest idealne (jeśli istnieją konstrukcje, które powinien zachować konstruktor). Poza tym byłaby naprawdę niestabilna i znacznie bardziej delikatna, gdybym musiała jawnie przekazać każdą inną wartość w instancji, którą chcę zmodyfikowaną kopię.

Nie mogłem nic na ten temat znaleźć, googlując lub w krótkim przeglądzie podręcznika do obsługi języka lub "Scala By Example" (który przeczytałem od początku do końca, ale nie pochłonąłem wszystkich jeszcze , więc może tam być).

widzę, że ta funkcja może mieć jakieś dziwne interakcje z ochroną dostępu Java stylu i podklasy mimo ...

+1

Czy to nie klasy przypadków, których szukasz? http://daily-scala.blogspot.com/2010/01/case-classes-in-28.html –

+0

Zobacz także http://stackoverflow.com/questions/3900307/cleaner-way-to-update-nested- struktury –

Odpowiedz

11

Możesz użyć do tego klas przypadków, ale nie musisz. Klasy przypadków nie są niczym magicznym - modyfikator case pozwala zaoszczędzić sporo pisania. Metoda kopiowania jest realizowana przy użyciu parametrów nazwanych i domyślnych. Nazwy są takie same jak pola, a wartości domyślne to bieżące wartości pól. Oto przykład:

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

Możesz użyć tego, podobnie jak metoda kopiowania dla klas przypadków. Parametry nazwane i domyślne to bardzo przydatna funkcja, a nie tylko metody kopiowania.

+2

Wow, jak bardzo tęskniłem za tym, że Scala nazywa przekazywanie parametrów? To będzie bardzo przydatne. Przyjmuję tę odpowiedź, ponieważ wyjaśnia ona, w jaki sposób działa metoda kopiowania w klasach spraw, a także w jaki sposób mogę zastosować te pomysły, nawet jeśli klasy przypadków nie są odpowiednie. – Ben

4

Jeśli obiekt planujesz nad modyfikacją jest klasą przypadek następnie można użyć wygenerowany automatycznie metoda kopiowania:

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

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

Jeśli zdefiniować swoją klasę jako case class, wygodne copy metoda jest generowany, a nazywając ją można określić za pomocą nazwanych parametrów nowych wartości dotyczących niektórych dziedzinach.

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) 

Działa to nawet z klas polimorficznych case:

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) 

Zauważ, że s2 ma inny typ niż s.

+0

Wielkie dzięki za edycję, Lukas, właśnie nauczyłem się czegoś nowego! –

+0

Dzięki za doskonałe przykłady! Polimorficzna kopia jest bardzo zła. – Ben

Powiązane problemy