Clojure 宏:从地图创建本地变量 [重复]

2024-05-06

我有这个示例代码,我通过迭代映射的键值对来创建变量。

(defmacro block [bindings & body] 
  `(let [
    ~@(mapcat (fn [[k v]] [(if (symbol? k) k (symbol (name k))) `~v]) bindings) ]
  ~body))

(block {:a 1 :b 2} (if true (prn "true" a b) (prn "false")))

效果很好。 输出:“真”1 2


但现在我想传递与汽车相同的地图,但是它抛出了异常。

IllegalArgumentException 不知道如何从以下位置创建 ISeq:clojure.lang.Symbol

(def ctx {:a 3 :b 4})

(block ctx (if true (prn "true" a b) (prn "false")))

当您传递一个引用包含映射的 var 的符号时,它不起作用的原因是因为宏只看到符号文字 - 而不是它引用的值。当您向其传递地图文字时,宏会看到地图文字。

如果您希望它也支持符号,您需要resolve符号引用的 var 并获取其值,例如(var-get (resolve bindings)):

(defmacro block [bindings & body]
  `(let [~@(mapcat (fn [[k v]] [(if (symbol? k)
                                  k
                                  (symbol (name k))) `~v])
                   (cond
                     (map? bindings) bindings
                     (symbol? bindings) (var-get (resolve bindings))
                     :else (throw (Exception. "bindings must be map or symbol"))))]
     ~@body))

(block ctx (if true (prn "true" a b) (prn "false")))
"true" 3 4
(block {:a 3 :b 4} (if true (prn "true" a b) (prn "false")))
"true" 3 4

还需要“拼接”body进入表格使用~@, 因为body即使它只包含一个表单,也将是一系列表单。

它还可以帮助您在排除故障时查看宏的扩展方式:

(macroexpand-1 '(block ctx (if true (prn "true" a b) (prn "false"))))
=> (clojure.core/let [a 3 b 4] (if true (prn "true" a b) (prn "false")))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Clojure 宏:从地图创建本地变量 [重复] 的相关文章

随机推荐

  • NHibernate 应如何更新映射为版本的属性

    使用流畅的 NHibernate 我在使用映射的类上有一个属性Version Version x gt x Version 当我保存对象时 Version 属性会按照我的预期在数据库中递增 但对象上的属性值似乎只是有时会发生变化 using
  • 您会将什么放入存储库类(数据访问层)的单元测试中?

    我想为我的数据访问层编写一个单元测试 以确保其中的一切正常工作 问题是 我应该把什么样的东西放入测试中 DAL 是静态的Repository隐藏底层 Fluent NHibernate 并通过一个公开的东西向公众公开的类IQueryable
  • 使用 Fig 时,为什么我的卷有时无法安装到 Docker 容器中?

    我在 Docker Fig 环境中看到一个奇怪的问题 我的假设是 这是由于将卷安装到容器的延迟造成的 但我不确定如何确认这一点 我有一个包含以下内容的容器 Dockerfile FROM busybox MAINTAINER Dan Rum
  • OPC-UA 的替代方案 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 作为访问由各种 PLC 组成的系统的过程数据的解决方案 是否有 OPC UA 的合适替代方案 独立于平
  • OS X Mavericks 上的 Python 3 分段错误

    我在 OS X Mavericks 上使用 Python 3 时遇到了分段错误 关于如何解决这个问题有什么建议吗 我尝试从Python站点重新安装该包 但这没有效果 如何在系统上重新编译 Python 3 这个问题的存在是因为这个bug h
  • 使用反射获取静态类列表

    很多问题都很接近 但没有一个能回答我的问题 如何使用 C 3 5 中的反射从程序集中获取所有静态类 我已经定义了所有类型 但没有 IsStatic 属性 计算 0 个构造函数确实很慢 而且也不起作用 有什么提示或一行代码吗 Chris 以下
  • Schema.org 用于列出文章的类别页面

    我正在使用微数据标记我的网站 并询问自己如何标记文章的列表 在类别页面上 我有一篇大文章已标记 但我不知道是否也应该标记该列表
  • formatFloat :将浮点数转换为字符串[重复]

    这个问题在这里已经有答案了 http golang org pkg strconv http golang org pkg strconv http play golang org p 4VNRgW8WoB http play golang
  • ANTLR4性能问题

    关于 ANTL4 解析的性能已经有一些讨论 例如 Antlr 4 解析大型 c 文件需要很长时间 https stackoverflow com questions 19311864 antlr 4 parsing large c file
  • CSS 定位相对于固定/绝对

    如果我对 CSS 显得很 菜鸟 请见谅 我一直在尝试设置以下 0 width 100 height y border 1px solid black a position fixed float left width x height y
  • iOS:UIScrollView 检测滑动手势

    我有一个 UIScrollView 它通过使用计时器自动滚动 每 3 秒滚动到下一页 类似于幻灯片 现在我想实现一个检测任何用户交互的函数 一旦用户与滚动视图交互就取消计时器 以便他可以自己滚动滚动视图 最好的方法是什么 ScrollVie
  • Flex 垂直数据网格

    我可以有一个垂直而不是水平显示数据的数据网格吗 例如 如果这是我的数据提供者 array firstname John lastname Doe array firstname Jack lastname Jill 我希望数据显示如下 Fi
  • 带子图聚合的递归查询(任意深度)

    我问了一个问题earlier https stackoverflow com questions 28036055 recursive query with sub graph aggreagation关于沿着图表聚合数量 提供的两个答案效
  • 使用 MathJax 排版/渲染动态内容

    我使用 MathJax 来显示数学方程 它在静态编写的数学中运行良好 但不适用于动态添加的数学 这是我的代码 Static div span x b pm sqrt b 2 4ac over 2a span div Dynamic div
  • Angular2 - *ngIf 和异步可观察量

    我在将 ngIf 与可观察变量一起使用时遇到问题 问题是 当我隐藏元素时 ngIf 然后再次显示 值将不会加载 因此 div someObservable async div 基本上当 showDiv 设置为true首先 加载了 someO
  • [现代] C++ 中 N 个变量的范围/循环

    遍历 N 个任意类型的变量来执行操作的简洁方法是什么 假设我有变量a b c d e并想要对他们所有人进行一些操作 使用 Boost Hana 和通用 lambda include
  • Ember:如何使用 i18n lib 翻译占位符?

    See http jsfiddle net cyclomarc 36VS3 1 http jsfiddle net cyclomarc 36VS3 1 我正在使用 Ember i18n lib 进行翻译 如何在 Ember TextFiel
  • 来自 jquery 事件的回调角度函数

    我正在使用 Angular5 并尝试获取 fullcalendar io jquery 插件的 dayClick 事件来回调角度组件 以便我可以打开从日历详细信息填充的角度组件对话框 要设置示例 请在控制台中执行以下操作 ng new pj
  • 跳转到脚本中的某些位置

    有没有办法让脚本跳转到命令提示符中的特定位置 例如 GOTO 我想让脚本结束时跳到开头 tag1 Read Host Enter tag cls sc exe tag1 start RemoteRegistry cls Start Slee
  • Clojure 宏:从地图创建本地变量 [重复]

    这个问题在这里已经有答案了 我有这个示例代码 我通过迭代映射的键值对来创建变量 defmacro block bindings body let mapcat fn k v if symbol k k symbol name k v bin