如何创建记录的新实例?
问题描述:
既然我已经定义(在这种情况下记录)两个对象:如何创建记录的新实例?
(defrecord rec1 [one two])
(defrecord rec2 [one two])
,我在列表中有(uninstanciated)这两个记录:
(def recs [rec1 rec2])
如何是最好的方式将这两个记录列入清单?
下面给出了一个例外
(map (fn [rec] (rec. 1 2)) recs)
,因为新的点构造函数需要一个类名符号。那么最好的办法是什么呢?到目前为止,反射似乎是唯一的出路:
(map #(clojure.lang.Reflector/invokeConstructor % (to-array [1 2 3])) recs)
这似乎只是一个过于丑陋(慢)的方式来进行调用对象的构造看似简单的任务。那么什么是正确的(或惯用的)方式?
答
你的问题我也不清楚,但这里有一些意见:
- REC1和REC2不是同一类型的不同构建函数,而不是单独的类型与1周的ctor(共捎带两个ctor有相同的arity /签名)
- 你的'uninstatiated list'没有意义。
- defrecord产生了一些辅助功能,只是这种使用...
我不知道你现在要做的,这里究竟都有些什么,可能说明你的要求的例子......
(def r1 (->rec1 1 2))
;=> #user.rec1{:one 1, :two 2}
(def c1 (rec1. 1 2))
;=> #user.rec1{:one 1, :two 2}
(def m1 (map->rec1 {:one 1 :two 2}))
;=> #user.rec1{:one 1, :two 2}
(def r2 (->rec2 1 2))
;=> #user.rec2{:one 1, :two 2}
(def c2 (rec2. 1 2))
;=> #user.rec2{:one 1, :two 2}
(def recs [(rec1. 1 2) (->rec1 1 2)])
(for [[n m] (partition 2 (range 4))] (->rec1 n m))
;=> (#user.rec1{:one 0, :two 1} #user.rec1{:one 2, :two 3})