gpt4 book ai didi

clojure - 使用 Clojure deftype 作为参数化函数

转载 作者:行者123 更新时间:2023-12-02 15:53:07 25 4
gpt4 key购买 nike

我正在尝试在编译器中使用 clojure,因此需要参数化对 deftype 的调用;但是,我很难使类型提示得以实现。考虑以下代码:

(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))))

以及来自 REPL 的以下 session :

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")

请注意,为间接类型生成的类已丢失直接类型所具有的 ^int 提示。我如何才能完成这些提示?

最佳答案

您需要将indirect-helper更改为读取

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

原因是^int解析为^后跟int; Clojure 1.2 中的 ^ 引入了读取器元数据(在 1.1 中,您可以使用 #^,它仍然有效,但在 1.2 中已弃用)。因此,direct 中的 ^int x读入作为名称为 clojure.lang.Symbol “x” ,其元数据映射为 {:tag int} (这里的 int 本身就是一个符号)。 (在本例中,符号的最后一个组成部分——它的命名空间——是nil。)

在问题文本中的indirect-helper版本中,^int附加到(symbol "x")——列表包含符号 symbol 和字符串 "x" (特别是 (list ^int (symbol "x")) 计算结果为1 个元素的列表)。一旦(symbol "x")被求值,这个“类型提示”就会丢失。为了修复问题,需要某种方法将元数据附加到由 (symbol "x") 生成的实际符号。

现在,在这种情况下,符号是在运行时生成的,因此您不能使用读取器元数据将类型提示附加到它。输入 with-meta,它在运行时附加元数据(并且在编写宏时经常有用,原因与此处相同),然后这一天就被保存了:

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

(顺便说一句,我认为 deftype 需要一个字段名称向量,但显然列表也可以工作......向量肯定仍然更惯用。)

关于clojure - 使用 Clojure deftype 作为参数化函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3330666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com