2015-06-20 26 views
3

我是Clojure的新手,我讀過它是一種功能性語言。它說,Clojure沒有變量,當我發現(定義5)時,它和變量有什​​麼區別?關於Vars Clojure的問題

我可以改變var後的值,所以它真的不同於變量嗎?我不明白區別。

回答

5

假設由variable你說的是指一個可變的存儲位置,我想最主要的區別(這取決於對哪種語言你比較)是,如果你動態地重新綁定Clojure中的var是在每個線程的基礎。

但長時間的答案是,你通常不會在Clojure中使用var,除非你真的需要引用一個可變的存儲位置。

Clojure贊成使用而不是參考文獻的不變性和編程。

您可以觀看Rich Hickey's talk關於值。

總結是,當你在Clojure中編程時,你所擁有的是,而不是引用可能會改變的位置(甚至可能被另一個線程改變)。

所以。

(let [a 1 
     _ (println a) => prints 1 
     a 2 
     _ (println a) => prints 2 
    ]) 

即使你在代碼「改變a」的,你不改變「老」 a的錯覺,你只是有一個新的價值。 (如果有人會看第一個定義,它仍然會看到值1)。

實際上,您可以看到作爲組合函數調用的作業順序調用,其中a被作用域中的替換,但根本不是相同的「變量」。

((fn [a] 
    (println a) => prints 1 
    ((fn [a] 
     (println a) => prints 2 
    ) 2) 1) 

儘管如此,如果你需要有許多潛在的線程訪問該存儲,Clojure gives youvarsatomsrefs

2

這是不正確的,Clojure中沒有變量可變存儲, 一世。即可變參考。但是,在計算過程中,它們不能用於存儲和查找,這些計算可以建模爲純數學函數。

不變性的概念是處理具體的價值,而不是一個或其他人可以改變的引用。就像1是一個值,你不能改變,在Clojure矢量[3 2]是你也不能改變的價值。例如,如果你的算法需要追加1到那個向量,它需要創建一個新的向量,讓原來的向量完好無損,而在命令式語言中,你可以「改變」向量,打破所有可能依賴它的東西。不變性的外露是你不必擔心這一點,並且你的代碼變得不太容易出錯。

Clojure以這種新創建的值高效地重用其基於的值的大部分內存的方式實現不可變數據結構。它們提供的讀寫性能(即創建新版本)幾乎與其可變對象相同的性​​能特徵。您可能想了解更多關於here的信息,Rich Hickey在與Brian Beckmann的對話this中做了一些很好的解釋。

0

想想def定義常數。可以通過再次調用def來改變,但您should not do it

關閉變量的東西是agents這是線程安全的。

(def counter (agent 0)) 
(send counter inc) 
@counter 
;;=> 1 

您還可以訪問Java類中的變量。

新類

(def object (ClassName.)) 

硒值

(.fieldName object) 

設定值

(set! (.fieldName object) 5) 

的沒有變量 「整」 點是讓程序自動線程安全的。這是因爲線程錯誤將在該線程上「始終」失敗1將告訴變量a爲1,線程b告訴a爲2,之後失敗。這也是使用純函數的原因 - 沒有變量「否」的線程問題。

另請參閱此question:Clojure differences between Ref, Var, Agent, Atom, with examples和這一個Clojure: vars, atoms, and refs (oh my)

在80%以上 - 不是100%處理「」。