1

鉴于我定义了两个对象(在本例中为记录):

(defrecord rec1 [one two])
(defrecord rec2 [one two])

我在列表中有这两条记录(未实例化):

(def recs [rec1 rec2])

如何在列表中实例化这两条记录的最佳方法是什么?

下面给出一个例外

(map (fn [rec] (rec. 1 2)) recs)

因为 new 和点构造函数需要一个类名符号。那么解决这个问题的最佳方法是什么?到目前为止,反射似乎是唯一的方法:

(map #(clojure.lang.Reflector/invokeConstructor % (to-array [1 2 3])) recs)

这似乎是一种过于丑陋(且缓慢)的方式来执行看似简单的任务,即在对象上调用构造函数。那么正确(或惯用)的方式是什么?

4

1 回答 1

2

你的问题我不清楚,但这里有一些观察:

  • rec1 和 rec2 不是同一类型的不同 ctor,而是不同的类型,每个类型都有 1 个 ctor(巧合的是,两个 ctor 具有相同的数量/签名)
  • 您的“未列出的列表”没有意义。
  • 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})
于 2012-04-23T22:14:26.567 回答