Clojure记录:如何根据属性名称获取暗示类型

9
我想知道是否有一种方法可以检索与使用defrecord声明的属性相关联的类型提示。例如,如果我有以下记录定义:
(defrecord Foo [^Integer id ^String description])

我想获取一个关于Foo类型的地图,它会给我属性及其暗示类型。我知道可以通过反射获取已声明属性的列表:
(->> record .getDeclaredFields (remove #(java.lang.reflect.Modifier/isStatic (.getModifiers #))))

这确实给了我一个声明字段的列表,但它们的类型是Object。我知道Clojure是一种动态语言,但当我需要时,如果类型能够返回给我就更好了。


在 Clojure 的未来版本中,当你这样做时,有可能/相当可能会得到实际的类型,即不要指望内部实现保持不变! - mikera
不确定这是否有帮助,但(let [i 42 desc "Forty two" record (Foo. i desc)] [(type (:id record)) (type (:description record))]) => [java.lang.Integer java.lang.String]。然而可能不是您想要的,因为:(let [i "Not and int" desc 999 record (Foo. i desc)] [(type (:id record)) (type (:description record))]) => [java.lang.String java.lang.Integer] - Wodin
2个回答

3

类型提示并不保存在任何地方。您可以通过为defrecord编写包装宏来管理此信息,以保留类型信息。您可以例如为记录类型生成一个构建函数,它会在字段上丰富实例元数据:

(defrecord-hinted Foo [^Integer id ^String description])

; you could then acces the type information with
(->> (meta (make-Foo 42 "forty two")) 
     ::field-types
     :id) ; => java.lang.Integer.class

1

请参见此问题的答案。目前似乎字段上的类型提示并没有被广泛使用,与函数参数和返回值上的提示不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接