如何创建记录的新实例?

问题描述:

既然我已经定义(在这种情况下记录)两个对象:如何创建记录的新实例?

(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})