gpt4 book ai didi

macros - 编写宏时获取原始符号名称

转载 作者:太空宇宙 更新时间:2023-11-03 18:50:40 25 4
gpt4 key购买 nike

我编写了以下宏,它定义了具有自定义字符串表示形式的记录。

(defmacro defrecord*
[rname args]
`(defrecord ~rname [~@args]
Object
(toString [_]
~(let [kvs (->> args
(map (fn [arg] [(str arg ": ") arg]))
(interpose ", ")
(apply concat))]
`(str ~rname "(" ~@kvs ")")))))

然而,toString 返回的结果并不完全符合我的预期。

(defrecord* Foo [bar baz]) 
(.toString (Foo. 3 4))

> "class user.Foo(bar: 3, baz: 4)"

在这种情况下,我希望我的 toString 返回 Foo(bar: 3, baz: 4)。我需要做哪些更改才能获得这种格式的字符串表示形式?

另外,如果有的话,我应该对上面的代码进行哪些更改以使其更加地道?

最佳答案

只需将 ~rname 替换为 '~rname - 您需要实际符号 Foo,而不是它在当前范围内的值,即user.Foo 类。

您还有 (apply concat)(interpose ", ") 顺序错误 - 您将处理 ", " 作为一个序列,并添加 \,\space 字符而不是单个字符串。一旦你交换了它,很明显你想要 mapcat 而不是 (apply concat (map ...))。所以我会用类似的东西替换你的整个 let-block:

`(str '~rname
"(" ~@(interpose ", "
(mapcat (fn [arg] [(str arg ": ") arg])
args))
")")

或者,如果您真的想提高性能,您可以在编译时而不是在运行时计算 ~(str "("rname)

不过请注意,从 Clojure 1.3 开始,记录已经以与此非常相似的方式打印,所以如果您这样做只是为了简化调试,请不要打扰。如果你这样做是因为你稍后要使用 .toString 的输出......好吧,无论是谁写了那个代码,都是可耻的,因为 .toString主要用于调试。

关于macros - 编写宏时获取原始符号名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11407759/

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