默认值记录构造函数中的值

时间:2015-05-06 13:40:27

标签: clojure

我不太明白

的错误
(defrecord Person [name age])

(defn make-person [& opts]
  (let [defaults {:age 18}]
    (map->Person (merge defaults opts))))

(make-person {:name "Jim"})
=> ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.util.Map$Entry  clojure.lang.APersistentMap.cons (APersistentMap.java:42)

如果我这样做:     (map-> Person(merge {:age 18} {:name" Jim"}))

我也可以让make-person函数使用非可选参数。

(defn make-person [opts]      
  (let [defaults {:age 18}]
    (map->Person (merge defaults opts))))

我已经为我想要做的事情找到了解决办法:

(defn make-person
  ([opts] (map->Person (merge {:age 18} opts)))
  ([] (map->Person {:age 18})))

所以我想我问,&在解构函数参数时真正做了什么?

1 个答案:

答案 0 :(得分:3)

& opts会返回一个序列,如果您传入地图,则会出现问题。

您可能希望将序列解构为:

(defn make-person [& [opts]]
   (map->Person (merge {:age 18} opts))

可让您(make-person)(make-person {:opt1 "foo" :opt2 "bar"})

您可以利用特殊语法来允许关键字args:

(defn make-person [ & {:as opts} ]
   (map->Person (merge {:age 18} opts))

允许你执行(make-person :opt1 "foo" :opt2 "bar")但是根据我的经验,如果你想在呼叫之外进行合并(你将在某一天),那么调用make-person会很困难(例如,如果你想{{1} }}