我正在尝试编写一个宏,它通过解构扩展为 let 形式。我的问题是我想要获得在 let 形式中定义的符号列表,包括通过解构获得的符号。
Use case
我正在尝试排除这种行为,例如进行验证:
(let [a (foo bar)
{x :x,
y :y,
{u :u, v: v :as nested-map} :nested} some-map]
(and x y nested-map u v ; testing truthiness
(valid-a? a)
(valid-x? x)
(valid-y? y)
(valid-nested? nested-map)
(valid-u-and-v? u v)
))
建议的解决方案
通过某种方式实现这一目标真是太好了and-let
我可以这样调用宏:
(and-let [a (foo bar)
{x :x,
y :y,
{u :u, v: v :as nested-map} :nested} some-map]
(valid-a? a)
(valid-x? x)
(valid-nested? nested-map)
(valid-u-and-v? u v))
我缺少什么
但我缺少某种访问 let 形式中绑定的符号列表的方法。如果我有类似的东西list-bound-symbols
函数,我可以这样做:
(defmacro and-let
"Expands to an AND close that previouly checks that the values declared in bindings are truthy, followed by the tests."
[bindings & tests]
(let [bound-symbols (list-bound-symbols bindings) ;; what I'm missing
]
`(let ~bindings
(and
~@bound-symbols
~@tests)
)))
有谁知道我该怎么做?
解构由clojure.core/destructure
功能。它是公共的,因此我们可以自己调用它并提取所有局部变量的名称,包括那些在解构中使用的命名中间结果:
(defmacro and-let [bindings & tests]
(let [destructured (destructure bindings)]
`(let ~destructured
(and ~@(take-nth 2 destructured)
~@tests))))
似乎有效:
(let [foo nil]
(and-let [a 1
[b c] [2 3]]
(nil? foo)))
;= true
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)