2011-06-27 11 views
7

Czytam książkę "Programowanie w Scali" przez Scala Creatora i jestem nieco zakłopotany na przykładzie Set.Zmienny i niezmienny zbiór scala, kiedy używać val i var

Tu jest za niezmienny Zestaw:

var jetSet = Set("Boeing", "Airbus") 
jetSet += "Lear" 
println(jetSet.contains("Cessna")) 

Jaki jest sens tego?

Zestaw jest niezmienny, ale zmienna jetSet jest zmienna. 1) Więc za każdym razem, gdy dodaję do zestawu za pomocą + = tworzy nowy zestaw? Więc zmienna wskazuje na nowy zestaw w pamięci?

2) Czy nie powinno być: val jetSet = set("cow","sheep","duck")? Dlaczego musi to być var? Czy jest jakiś powód używania var dla niezmiennego zestawu?

Odpowiedz

16

Zaletą niezmiennych struktur danych, w tym przypadku Ustaw, jest to, że są trwałe. Na przykład:

var jetSet1 = Set("Boeing", "Airbus") 
val jetSet2 = jetSet1 // ... imagine jetSet2 is somewhere else in the program 
jetSet1 += "Lear" 
assert(!jetSet2.contains("Lear")) 

Niezmienność tych Zestaw przedmiotów ułatwia rozumować o programie, ponieważ aktualizacje zmiennej jetSet1 nie mają skutków ubocznych w innych częściach kodu (w tym przypadku stosuje się wszędzie tam, gdzie jetSet2). Chociaż z tego przykładu nie wynika jasno, są sytuacje, w których wygodnie jest przechowywać niezmienne wartości w zmiennych odniesieniach var; najczęściej, var będzie miał ograniczony zakres (np. lokalny dla funkcji).

Niezmienne struktury danych często mają sprytne implementacje, które są dość wydajne. Niestety interfejs API Scala nie jest dobrze udokumentowany pod względem wydajności, ale oczekiwałbym, że większość operacji będzie w przybliżeniu czasem O (log N). Na przykład, biorąc pod uwagę duży niezmienny zbiór s, należy sprawnie zbudować s + x, nowy zestaw z dodatkowym elementem. Oczywiście, niezmienność gwarantuje, że również zachowana jest s. Pod maską, s i s+x będą przechowywane przy użyciu pewnego rodzaju struktur danych drzewa ze współużytkowanymi komponentami.

Tytuł pytania sugeruje, że szukasz również porady na temat używania val lub var. Zasadą jest używanie val, kiedy tylko możesz. Jeśli wymagany jest var, spróbuj ograniczyć zakres zmiennej tak bardzo, jak to możliwe.

+2

Nie bezpośrednio w interfejsie API, ale wydajność * jest * [udokumentowana] (http://www.scala-lang.org/docu/files/collections-api/collections.html). – Debilski

+0

Dzięki za link –

+1

Wiele operacji jest, jak można się spodziewać, O (log n), ale należy podkreślić, że podstawa logarytmu jest tak wysoka, że ​​skutecznie wykonuje operacje O (1). Praktycznie rzecz ujmując, operacje na niezmiennych strukturach danych Scala są w stałym współczynniku odpowiednich operacji na ich zmiennym kuzynie. –

6

var pozwala na ponowne przypisanie do zmiennej, traktuj ją jako normalną deklarację zmiennych w Javie. Ale w powyższym przypadku, nawet jeśli przenosisz się do tej samej zmiennej, to zawsze jest inny zestaw, ponieważ używasz niezmiennego.

Celem tego przykładu było pokazanie, że nawet jeśli spróbujesz "zmodyfikować" niezmienny zbiór, modyfikacje utworzą nową kolekcję zamiast dotknąć oryginalnej. Gdyby autor użył val (zgodnie z final w Javie), musiałby wprowadzić zmienną w zakresie, aby utrzymać nowy niezmienny zestaw. Myślę, że najprawdopodobniej został użyty var, aby ten przykład był prosty.

0

Nie możesz wykonać +=, jeśli używasz val. val/var/def dotyczy symbolu, a nie jego wartości/implementacji spróbuj val ... otrzymasz kompilację error.

+2

-1 Możesz zrobić '+ =' na 'val x: mutable.Set'. –

Powiązane problemy