2013-03-26 17 views

Odpowiedz

8

Zmienne są niezmienne w Clojure. Więc nie należy próbować zmienić wartość foo, ale zamiast tego, „tworzyć” nową foo:

(def foo2 (+ foo 0.1)) 

... lub, jeśli w pętli, powtarzać z nową wartość:

(loop [foo 5.0] 
    (when (< foo 9) 
    (recur (+ foo 0.1)))) 

... lub, jeśli foo jest atom, swap! ją nową wartość:

(def foo (atom 5.0)) 
(swap! foo (partial + 0.1)) 

polecam zacząć od czytania the rationale of Clojure.

+1

Ukazywanie varów jako jedynego sposobu na tworzenie nowej wartości jest mylące - w większości przypadków, gdy chcemy zastąpić wartość innym, są one niewłaściwym narzędziem. Atomy, pętle itp. Powinny prawdopodobnie mieć bardziej widoczne miejsce w przykładach. –

+2

['swap!'] (Http://clojuredocs.org/clojure_core/clojure.core/swap!) Pobiera funkcję i argumenty, aby dokonać aktualizacji, więc możesz napisać to tak, zamiast używać 'partial':' (swap! foo + 0.1) ' – DaoWen

3

odpowiedź blacksad obejmuje definiowanie vars więc chciałbym tylko dodać inne zakresy, w których może chcesz mieć wartość, która zwiększa się z inną wartością:

w zakres lokalnej funkcją jest:

user> (defn my-function [x] 
     (let [y (inc x) 
       z (+ x y)] 
      [x y z])) 
#'user/my-function 
user> (my-function 4) 
[4 5 9] 

i jeśli chcemy budować wartość stopniowo, aby proces bardziej jasne:

user> (defn my-function [x] 
     (let [y (inc x) 
       z (+ x y) 
       z (+ z 4) 
       z (* z z)] 
      [x y z])) 
#'user/my-function 
user> (my-function 4) 
[4 5 169] 

To może sprawić, że proces bardziej reprezentacyjny, ty nie jest to "sposób na odzyskanie zmiennych" i jest naprawdę użyteczny tylko w ograniczonych kontekstach. Ten wzorzec jest używany w makrach wątków clojure.core.

+0

Czy' let * 'to tylko podpowiedź (że przypisania nie są niezależne), czy też zachowuje się inaczej od' let'? – Blacksad

+0

let to makro wywołujące połączenie * https://github.com/clojure/clojure/blob/c6756a8bab137128c8119add29a25b0a88509900/src/clj/clojure/core.clj#L4035 –

+1

Nie rozumiem, dlaczego 'let *' jest tutaj. To oczywiście nie jest to, co pisalibyście w prawdziwym życiu, i nie wydaje się, aby służył w tym kontekście jakimkolwiek instrukcjom. To po prostu odwraca uwagę od głównego punktu, w jaki sposób używać 'let' do tworzenia nowych zakresów. – amalloy

Powiązane problemy