以下是代码:
(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
在这段代码中,我定义了一个名为entry的映射,其中包含:name和a:num,然后我把它放在一个列表中,然后我尝试打印:name的第一个(也是唯一的)元素的:name字段列表。 (或者至少这是我认为我的代码所做的事情:o)
我可以在将其放入列表之前从条目映射中访问名称,但是一旦它在列表中,我就会收到此错误。我应该给予什么?
答案 0 :(得分:3)
有两个问题。
首先,对于包含要解析的符号的列表(如您的情况中的符号条目),您必须使用syntax-quote(反引号)而不是常规引号(撇号);所以这一行:
(def tempList '(entry))
应该是:
(def tempList `(entry))
或者只是(使用矢量,这在Clojure中更惯用且更容易使用):
(def tempList [entry]) ; no quoting needed for vectors
然后,更改此行
(println (get (nth tempList 0) (:name)))
要么:
(println (get (nth tempList 0) :name))
或者这个:
(println (:name (nth tempList 0)))
答案 1 :(得分:2)
在列表中使用nth
是一个坏主意,因为它必须每次都进行线性搜索以检索元素。 Vector是这里使用的正确集合类型。
向量是指数与值的“映射”。如果您使用向量而不是列表,则可以执行此操作:
(:name (tempList 0))
或者:
(get (get tempList 0) :name)
或者:
(get-in tempList [0 :name]))
答案 2 :(得分:1)
从第3行的(:name)取消()。 :关键字是将地图作为参数并“自我查找”的功能,虽然它在这种情况下使错误更加混乱,但却非常方便
(get (nth '({:name "asdf"}) 0) :name))
答案 3 :(得分:1)
我会写这样的代码:
(def entry {:name tempName :num tempNum})
(def tempList (list entry))
(println (:name (first tempList)))
请注意,first
比使用nth
更加整洁,关键字可以充当在地图中查找自己的功能。另一种等效方法是组合函数并将它们应用于列表:
((comp println :name first) tempList)