2012-04-23 148 views
1

既然我已經定義(在這種情況下記錄)兩個對象:如何創建記錄的新實例?

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

這似乎只是一個過於醜陋(慢)的方式來進行調用對象的構造看似簡單的任務。那麼什麼是正確的(或慣用的)方式?

回答

2

你的問題我也不清楚,但這裏有一些意見:

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