2014-09-22 96 views
1

這個問題的標題可能超過了指定的實現,但想法很簡單,我想創建一個記錄或類似的東西,它可能是一個由deftype聲明的類型的映射,等等...我想創建一個字符串ID和int年齡的對象,但我想將ID轉換爲一個UUID和年齡爲一個INT,如果它還沒有。我如何慣用這樣做?Clojure:如何掛入Defrecord構造函數

到目前爲止,我有這樣的事情:

(let [item (my.model/map->Item { 
    :id (UUID/fromString "62c36092-82a1-3a00-93d1-46196ee77204") 
    :age (int 6)})]) 

,但我不想這樣做既每次我創建一個項目時這些操作的,我想在1處的邏輯。我可以做一個輔助功能來做到這一點,但是在deftype或defrecord中是否支持這個功能?

回答

3

最簡單的方法是使用一個函數,它接受你的輸入地圖並從中構建你的Item。

(defn make-item 
    [{:keys [id age] :as input}] 
    {:pre [(string? id) 
     (number? age)]} 
    (-> input 
     (update-in [:id] #(UUID/fromString %)) 
     (update-in [:age] int) 
     my.model/map->Item)) 

隨着您需要更多按鍵或更嚴格的約束,並適應其他記錄類型,這將很好地縮放。

+0

不錯的主意,謝謝 – 2014-09-22 22:49:36