2009-07-13 65 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)