2017-10-12 6 views
2

Pourquoi la clause case ne correspond-elle pas au type d'enregistrement?La clause case ne correspond pas au type d'enregistrement

(defrecord Rec []) 
=> fargish.user.Rec 

(def rec (->Rec)) 
=> #'fargish.user/rec 

(case (type rec) Rec :YES) 
=> IllegalArgumentException No matching clause: class fargish.user.Rec fargish.user/eval25147 (form-init131856794870899934.clj:1) 

Si vous vous demandez, oui, l'expression de cas et le test constant sont égaux:

(= (type rec) Rec) 
=> true 

Répondre

2

Rec n'est pas une compilation littérale. Citant https://clojuredocs.org/clojure.core/case:

Toutes sortes d'expressions constantes sont acceptables dans les cas, y compris les nombres, des chaînes, des symboles, des mots-clés, et (Clojure) des composites de ceux-ci.

Alternatives:

(cond 
    (= (type rec) Rec) :YES) 
;;=> :YES 
(condp = (type rec) 
    Rec :YES) 
;;=> :YES 
+0

Ahhhh, il est logique après tout. De nombreuses années de C m'ont fait penser qu'un enregistrement est une structure (une chose à la compilation). Merci pour les alternatives. Je pensais que Clojure aurait un moyen facile de faire cela qui n'impliquait pas d'aller jusqu'au bout pour définir un multiméthode! :) –

+1

Pas de problème. 'case' concerne les constantes. 'cond' est un usage général. Jusqu'à ce que je lise les documents, je pensais qu'un enregistrement était aussi une constante. Peut-être qu'une autre réponse viendra nous dire exactement pourquoi un enregistrement n'est pas une constante. –

+0

Encore une autre option est '(instance? Rec rec)'. –