2015-06-11 67 views
5

我剛剛開始學習clojure,並一直在閱讀一些簡單的例子,然後盡我所能去理解概念。clojure'val'返回這個值是什麼?

但是我對val在下面的例子中做了什麼感到困惑。這已從Clojure doc示例中獲得,用於val

(first {:one :two}) ;; => [:one :two] 

在這裏,與hash-map:one一個鍵和的:two的值被傳遞給first。在幕後,Clojure將hash-map轉換爲sequencevectors。由於此sequence中只有一個vector,因此它返回[:one :two]

(val (first {:one :two})) ;; => :two 
(val [:one :two]) ;; => ClassCastException clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry 
(val {:one :two}) ;; => ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.util.Map$Entry 

如果我嘗試致電val一個(我認爲)一個hash-map(我意識到這實際上是一個「老大難陣圖」),我得到的異常如上面看到的。

我也迷茫了以下內容:

(first {:one :two}) ;; # => [:one :two] (this is a vector right?) 
(val [:one :two]) ;; # => ClassCastException (why doesn't this give back the same result as the example above?) 

爲什麼我不能只是(first {:one :two})結果插入val,並得到同樣的結果?


此外,頁面上列出的另一個例子是:

(map val {:a 1 :b 2}) ;; => (1 2) 

以下是我讀線。以array-map{:a 1 :b 2}。對於每個鍵值對,請在該對上調用val以返回值。將所產生的電話的sequence返回map。這是解決問題的正確方法嗎?

一如既往,感謝您的任何幫助。

+3

地圖條目是一個向量,但並非所有向量都是地圖條目。 'val'只適用於地圖條目。 – noisesmith

+1

... to wit,'(type(first {:one:two}))'=>'clojure.lang.MapEntry' – Thumbnail

回答

6

地圖的序列產生MapEntry值作爲你已經注意到,它看起來像,可以與載體

user=> (= (first {:a 1 :b 2}) [:a 1]) 
true 

相提並論,但不是同一類

user=> (= (class (first {:a 1 :b 2})) (class [:a 1])) 
false 

因此,儘管對(first {:a 1})的REPL輸出看起來像一個載體,它不是,它是一個MapEntry,所以它可以傳遞給val,但矢量[:a 1]不能,因此類轉換異常。

您對圖所做的操作在高層次上是正確的,更具體一點可能是「對於序列中來自{:a 1:b 2}(即MapEntry值)的每個條目,調用函數val對每個項目(一個MapEntry),並從結果中生成一個序列「。

這將解釋爲什麼像

user=> (map val '([:a 1] [:b 2])) 

同樣會引起ClassCastException S作爲序列生成Vector元素,不MapEntry元素。

5

val返回地圖條目的值,而不是地圖。

(first {:one :two})返回所述第一映射條目(儘管它似乎只是一個VEC)

(map val {:one :two})返回的每個條目的值,並且等同於(vals {:one :two})

2
(first {:one :two}) ;; # => [:one :two] (this is a vector right? No, it's not.) 

[:one :two]在這種情況下是一個MapEntry,不是矢量。

相關問題