我不太明白
的错误(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})))
所以我想我问,&
在解构函数参数时真正做了什么?
答案 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} }}