2010-07-25 21 views
7

Bir derleyicide clojure kullanmaya çalışıyorum ve bu nedenle çağrıları deftype; Ancak, tür ipuçlarının devam etmesini zorlaştırıyorum. Repl gelenClojure deftype parametreli bir işlev olarak kullanılıyor

(defn describe [x] 
    (let [fields (.getDeclaredFields x) 
     names (map #(.getName %) fields) 
     types (map #(.getType %) fields)] 
    (interleave types names))) 

(defn direct [] (deftype direct-type [^int x])) 
(defn indirect-helper [] (list ^int (symbol "x"))) 
(defn indirect [] (eval `(deftype ~(symbol "indirect-type") ~(indirect-helper)))) 

Ve aşağıdaki oturumu: Aşağıdaki kodu düşünün dolaylı tipi için oluşturulan sınıf^int kaybettiğini

Clojure 1.2.0-master-SNAPSHOT 
1:1 user=> #<Namespace dataclass> 
1:2 dataclass=> (direct) 
dataclass.direct-type 
1:3 dataclass=> (indirect) 
dataclass.indirect-type 
1:4 dataclass=> (describe direct-type) 
(int "x") 
1:5 dataclass=> (describe indirect-type) 
(java.lang.Object "x") 

Bildirim direkt tip sahip olduğunu ima. Taşımak için o ipuçlarını nasıl alabilirim?

cevap

7

Sen

(defn indirect-helper [] [(with-meta (symbol "x") {:tag 'int})]) 

okumaya indirect-helper değiştirmeniz gerekir nedeni ^intint ardından ^ olarak ayrıştırır olmasıdır; ^, Clojure 1.2'de, okuyucu meta verilerini tanıtır (1.1'de hala çalışır, ancak 1.2'de kullanımdan kaldırılmış olan #^ kullanırsınız). Böylece direct yılında ^int x ismi "x" ve meta verilerini haritası {:tag int} bir clojure.lang.Symbol olarak yılında okuma alır (int burada kendisini bir sembol anlamına gelir). (Sembolü son bileşeni - onun ad - bu durumda nil içindir.) ^int(symbol "x") ekli alır soru metinden indirect-helper sürümünde

- sembolünü symbol ve dize içeren liste "x" (özellikle (list ^int (symbol "x"))'un 1 elemanın bir listesini değerlendirdiği anlamında). Bu "tip ipucu" (symbol "x") değerlendirildiğinde kaybolur. Bir şeyleri düzeltmek için, (symbol "x") tarafından oluşturulan gerçek sembole meta veri eklemenin bir yolu gereklidir.

Bu durumda, sembol çalışma zamanında oluşturulur, bu nedenle tür ipucunu eklemek için okuyucu meta verilerini kullanamazsınız.

user> (indirect) 
user.indirect-type 
user> (describe indirect-type) 
(int "x") 

(BTW, deftype alan adlarının bir vektör beklenen düşündüm: zamanında meta verdiği (ve burada olduğu gibi aynı nedenle yazı makrolarında sıklıkla yararlıdır) ve günlük olarak kaydedilir with-meta, Enter , ama görünüşe göre bir liste de çalışır ... Bir vektör hala daha idiomatic.)

İlgili konular