3

这是代码:

(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 和一个 :num,然后我把它放在一个列表中,然后我尝试打印列表的第一个(也是唯一一个)元素的 :name 字段。(或者至少这是我认为我的代码所做的:o)

在将其放入列表之前,我可以从条目映射中访问名称,但是一旦它在列表中,我就会收到此错误。我应该给什么参数?

4

4 回答 4

3

有两个问题。

首先,对于包含要解析的符号的列表(例如您的情况下的符号条目),您必须使用语法引号(反引号)而不是常规引号(撇号);所以这一行:

(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)))
于 2009-07-13T22:36:02.673 回答
2

在列表上使用nth是一个坏主意,因为它必须每次都进行线性搜索来检索您的元素。向量是在这里使用的正确集合类型。

向量是索引到值的“映射”。如果你使用向量而不是列表,你可以这样做:

(:name (tempList 0))

或者:

(get (get tempList 0) :name)

或者:

(get-in tempList [0 :name]))
于 2009-07-13T23:14:49.553 回答
1

我会这样写你的代码:

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

(def tempList (list entry))

(println (:name (first tempList)))

请注意,first这比使用要简洁得多nth,并且关键字可以充当在地图中查找自身的函数。另一种等效的方法是组合函数并将它们应用于列表:

((comp println :name first) tempList)
于 2009-07-21T02:07:12.057 回答
1

从第 3 行的 (:name) 中取出 ()。:keywords 是将地图作为参数并“查找自己”的函数,尽管在这种情况下它会使错误更加混乱,但它非常方便

(get (nth '({:name "asdf"}) 0) :name))
于 2009-07-13T22:45:45.103 回答