5

我正在尝试调用clojure.walk/stringify-keys可能包含记录实例的地图。由于 stringify-keys 是递归的,它会尝试转换我记录中的键(因为(map? record-var)是真的),这会导致错误。有什么方法可以判断一个 var 是否是一个记录而不仅仅是一个 Clojure 映射?我想提供我自己的stringify-keys记录感知实现。

当前的实施stringify-keys导致以下情况:

(use '[clojure.walk :only [stringify-keys]])

(defrecord Rec [x])    

(let [record (Rec. "foo")
      params {:x "x" :rec record}]
    (stringify-keys params))

这会导致以下异常: UnsupportedOperationException Can't create empty: user.Rec user.Rec (NO_SOURCE_FILE:1)

4

2 回答 2

5

记录似乎实现了 IRecord 标记接口:

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

user=> (require '[clojure.reflect :as r])
nil
user=> (:bases (r/reflect Rec))
#{java.io.Serializable clojure.lang.IKeywordLookup clojure.lang.IPersistentMap clojure.lang.IRecord java.lang.Object clojure.lang.IObj clojure.lang.ILookup java.util.Map}

user=> (instance? clojure.lang.IRecord (Rec. "hi"))
true

更新 1.6 现在具有record?功能

于 2012-05-14T19:21:55.850 回答
1

您可以检查每个成员的类型,看看它是否真的是地图或其他东西(假设其他东西是记录)

user> (type {:a 1 :b 2})
clojure.lang.PersistentArrayMap
于 2012-05-14T19:16:32.510 回答