2009-07-13 63 views
3

訪問的地圖列表中下面的代碼:Clojure中

(def entry {:name tempName :num tempNum}) 

(def tempList '(entry)) 

(println (get (nth tempList 0) (:name))) 

Exception in thread "main" java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :name 

在此位的代碼,我定義了一個地圖名爲包含條目:名稱和:NUM,然後我把它放在一個列表,然後我嘗試打印列表中第一個(也是唯一)元素的name字段。 (或者至少這是我覺得我的代碼呢:O)

我可以從條目映射訪問名字,我把它放在名單之前,但一旦它在列表中我得到這個錯誤。我應該給的是什麼樣的參數?

回答

3

有兩個問題。首先,對於包含要解析的符號的列表(例如您的案例中的符號條目),您必須使用syntax-quote(反引號)而不是常規引號(撇號);否則,您將不得不使用syntax-quote。所以這一行:

(def tempList '(entry)) 

應該是:

(def tempList `(entry)) 

或只是(使用的載體,這是更慣用的和更容易Clojure中使用):

(def tempList [entry]) ; no quoting needed for vectors 

然後,切換此行

(println (get (nth tempList 0) (:name))) 

to e ither此:

(println (get (nth tempList 0) :name)) 

或此:(:名稱)3號線

(println (:name (nth tempList 0))) 
1

從取()關閉。 :關鍵字是拿一張地圖作爲參數,「看他們自己了」,這是很方便的,雖然它使誤差略微在這種情況下

 
(get (nth '({:name "asdf"}) 0) :name)) 
2

名單上使用nth更加混亂是一個糟糕的主意,因爲功能它每次都必須執行線性搜索來檢索元素。向量是在此使用的正確的集合類型。

載體是指數的「映射」值。如果您使用的是矢量,而不是一個列表,你可以這樣做:

(:name (tempList 0)) 

或者:

(get (get tempList 0) :name) 

或者:

(get-in tempList [0 :name])) 
1

我會寫你這樣的代碼:

(def entry {:name tempName :num tempNum}) 

(def tempList (list entry)) 

(println (:name (first tempList))) 

注意first比使用nth更整潔,也可以爲關鍵字的功能作用看自己了在地圖上。另一種等價的方法是組合的功能,並將其應用到列表:

((comp println :name first) tempList)