gpt4 book ai didi

dictionary - 用于创建 map 的 Clojure 宏

转载 作者:行者123 更新时间:2023-12-02 04:54:52 25 4
gpt4 key购买 nike

我有一个用于创建 HashMap 的宏。我应该发送混搭的名称和通过调用函数获得的内容(在本例中它是一个函数 xx)。

(defmacro data-for-mashup [mashup-name func]  
`(map {} {:title :content} {~mashup-name (~@func)}))

宏应该有任何混搭名称和任何功能,这就是为什么我希望它是一个宏。

当我调用它时,我希望结果看起来像这样

{:title "Events Mashup"
:content [{ :event-name "event name 1"
:performer "performer 1"
:date "date 1"
:start-time "start time 1"
:end-time "end time 1"}
{:event-name "event name 2"
:performer "performer 2"
:date "date 2"
:start-time "start time 2"
:end-time "end time 2"}]}

content标签的值其实是一个映射向量。

调用宏应该得到这样的结果

(data-for-mashup "events" (xx))  

在 REPL 中我得到了这个结果

(["events" #<datamodel$xx mashup_dsl.datamodel$xx@530f0fbd>])  

macroexpand-1 结果

(macroexpand-1 `(data-for-mashup "events" (xx)))  
(clojure.core/map {} {:title :content} {"events" mashup-dsl.datamodel/xx})

(xx 是我命名空间中的一个函数。)

实际上我希望它扩展到这个

(map {} {:title :content} {"events" (xx)})  

我做错了什么?

最佳答案

首先,您是要创建对映射的调用还是 HashMap ?

map 用于将其第一个参数应用于其他参数的每个元素。将 {} 应用于某物不会生成 HashMap 。对于任何单个参数,一个空的 hashmap 将返回 nil。

user> (map {} [:a :b :c])
(nil nil nil)

作为函数提供给空 hashmap 的两个参数将始终返回第二个参数。你想在这里做什么?

user> ({} :a 0)
0

user> (map {} [:args :here :are-meaningless] (range))
(0 1 2)

接下来,~@ 从参数中取出顶层嵌套。如果要在列表中返回函数,则需要围绕它构造一个列表。引号(也写为 ')将阻止一对括号导致函数的应用,而是构造一个列表。

user> (macroexpand-1 ''(+))
(quote (+))

user> (quote (+))
(+)

user> (defmacro data-for-mashup [mashup-name func]
`(map {} {:title :content} {~mashup-name '(~@func)}))
#'user/data-for-mashup
user> (macroexpand-1 '(data-for-mashup "events" (+)))
(clojure.core/map {} {:title :content} {"events" (quote (+))})
user> (data-for-mashup "events" (+))
(["events" (+)])

这等同于不使用 ~@,只是直接使用 ~,但引用它返回的内容。

user> (defmacro data-for-mashup [mashup-name func]  
`(map {} {:title :content} {~mashup-name '~func}))
#'user/data-for-mashup
user> (macroexpand-1 '(data-for-mashup "events" (+)))
(clojure.core/map {} {:title :content} {"events" (quote (+))})
user> (data-for-mashup "events" (+))
(["events" (+)])

如果您正在尝试构建 HashMap ,我认为您可能需要以下定义之一:

user> (defmacro data-for-mashup [mashup-name func]  
`(zipmap [:title :content] [~mashup-name '~func]))
#'user/data-for-mashup
user> (data-for-mashup "events" (+))
{:content (+), :title "events"}

user> (defn data-for-mashup [mashup-name val] (zipmap [:title :content] [mashup-name val]))
#'user/data-for-mashup
user> (data-for-mashup "events" (+))
{:content 0, :title "events"}

关于dictionary - 用于创建 map 的 Clojure 宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18173311/

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