记录构造函数中的默认值

Defaults values in record constructors

我不太明白

有什么问题
(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})))

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

& optsreturns一个序列,如果传入一个map就会有问题

您可能想像这样解构序列:

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

这让你可以做 (make-person)(make-person {:opt1 "foo" :opt2 "bar"})

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

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

允许你做 (make-person :opt1 "foo" :opt2 "bar") 但根据我的经验,如果你想在通话之外进行合并(你有一天会)(即如果你想 (make-person (merge some-opts some-other-opts)