我想实现在最近定义了符号本身的宏中返回名称空间解析符号:
(ns my-namespace)
(defmacro def&resolve [a b]
`(do
(def ~a 12)
(def ~b ~(resolve a))))
(def&resolve foo bar)
bar ;=> nil
在示例bar
中返回nil。但是,我希望它返回my-namespace.foo
。我知道这是行不通的,因为在调用resolve
时,尚未定义a
。但是,对于我的用例[1],我需要a
在宏扩展时进行名称空间解析。
在下一次运行中,我想在宏扩展时声明a
(这是否有意义?),因此,在调用resolve
时强制它出现在当前ns中。 / p>
(defmacro def&resolve [a b]
(declare a)
`(do (def ~a 12)
(def ~b ~(resolve a))))
(def&resolve foo bar)
bar ;=> nil
也不起作用。
我该如何定义某些内容,并在宏扩展名称空间中对其进行解析?
[1]我的用例如下:我想定义一个函数束并将其添加到def绑定的元信息中(因此,在宏扩展时需要它)。目前,我只存储符号,没有存储定义函数的名称空间。
答案 0 :(得分:0)
Sub colocar_Linha()
ultima_linha = Worksheets("Sheet2").Range("A3").CurrenRegion.Rows.count
i = 3
While i <= ultima_linha
If Not (Cells(i, 1).value = Cells(i - 1, 1). value) Then
Rows(i).Insert shift:=xlShiftDown
i = i + 1
ultima_linha = ultima_linha + 1;
End If
i = i + 1
Wend
End Sub
答案 1 :(得分:0)
由于将在运行时定义/创建变量,因此宏一旦完成工作并消失,宏就可以预测变量的名称并直接创建符号,而无需进行往返通过名称空间并返回
让我们先手动进行
user> (def foo)
#'user/foo
user> (resolve 'foo)
#'user/foo
看起来不错,现在让我们通过创建符号来做到这一点:
user> (symbol (str *ns* "/" "foo"))
user/foo
并将其复制到宏定义中:
user> (defmacro def&resolve [a b]
`(do
(def ~a 12)
(def ~b ~(symbol (str *ns* "/" "foo")))))
#'user/def&resolve
进行测试
user> (def&resolve foo bar)
#'user/bar
user> bar
12
此方法优于在宏扩展时使用intern
在虚拟空间中使用伪值创建符号的方法,然后在宏扩展时也使用resolve
对其进行符号化。结果相同。这种方法的优势在于,它确实可以像您原始问题中那样在宏扩展时解决问题。
user> (do (intern *ns* 'a :dummy-value)
(resolve 'a))
#'user/a
尽管我建议使用符号生成方法。
答案 2 :(得分:0)
语法引号的嵌套很有帮助,在〜a处附加引号:
(defmacro def&resolve
[a b]
`(do
(def ~a 12)
(def ~b ~`(resolve '~a))))
#'test-project.core/def&resolve
test-project.core=> (macroexpand '(def&resolve foo bar))
(do (def foo 12) (def bar (clojure.core/resolve (quote foo))))
test-project.core=> (def&resolve foo bar)
#'test-project.core/bar
test-project.core=> foo
12
test-project.core=> bar
#'test-project.core/foo
如果您实际上想获取foo的值,那么必须通过解析来对(@)var进行解引用:
(defmacro def&resolve
[a b]
`(do
(def ~a 12)
(def ~b @~`(resolve '~a))))
test-project.core=> (def&resolve foo bar)
#'test-project.core/bar
test-project.core=> bar
12