Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何编写Clojure宏以获取var';s值多少?_Clojure - Fatal编程技术网

如何编写Clojure宏以获取var';s值多少?

如何编写Clojure宏以获取var';s值多少?,clojure,Clojure,我可以写一个宏让两者都可以吗 (M2) 及 (让[i 2](mi)) 获取“this is v2”这在没有宏的情况下是可能的: user=> (def v-1 "this is v1") user=> (def v-2 "this is v2") user=> (defmacro m [v] (symbol (str "v-" v))) user=> (m 1) "this is v1" us

我可以写一个宏让两者都可以吗

(M2)

(让[i 2](mi))


获取“this is v2”

这在没有宏的情况下是可能的:

user=> (def v-1 "this is v1")
user=> (def v-2 "this is v2")
user=> (defmacro m [v] (symbol (str "v-" v)))
user=> (m 1)
"this is v1"
user=> (m 2)
"this is v2"
user=> (let [i 2] (m i))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: v-i in this context, compiling:(NO_SOURCE_PATH:73:12)
如果需要,也可以使用宏:

(defn m [v] (var-get (resolve (symbol (str "v-" v)))))

(m 1) ;; => "This is v1"
(let [i 2] (m i)) ;; => "This is v2"

这在没有宏的情况下是可能的:

user=> (def v-1 "this is v1")
user=> (def v-2 "this is v2")
user=> (defmacro m [v] (symbol (str "v-" v)))
user=> (m 1)
"this is v1"
user=> (m 2)
"this is v2"
user=> (let [i 2] (m i))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: v-i in this context, compiling:(NO_SOURCE_PATH:73:12)
如果需要,也可以使用宏:

(defn m [v] (var-get (resolve (symbol (str "v-" v)))))

(m 1) ;; => "This is v1"
(let [i 2] (m i)) ;; => "This is v2"

普通函数似乎更可能是您想要的

不过,首先,为了解决最初的问题,如果您想坚持使用宏,宏是在编译时调用的常规函数,因此您可以使用变量的符号名查找变量,并使用
deref
获取其值,就像在(您的应用程序,而不是宏的)运行时一样:

请注意,上面的
1
是此处的实际宏扩展。这与

(defmacro var-value [vsym] @(resolve vsym))

(def foo 1)

(var-value foo)
;= 1
(macroexpand-1 '(var-value foo))
;= 1
后者扩展为调用
resolve
,因此给定实现的查找将推迟到应用程序的运行时

(defmacro var-value [vsym] `@(resolve ~vsym))
因此,无论在哪里调用宏,此代码都将被内联

当然,宏也可以扩展为符号–例如

(macroexpand-1 '(var-value foo))
;= (clojure.core/deref (clojure.core/resolve foo))
将生成扩展,如
v-1
(用于
(前缀为var1)
)等

回到这里的宏适用性主题,但是,如果使用宏,生成扩展所需的所有信息必须在编译时可用,因此,通常不能在扩展中使用
let
/
循环
局部变量或函数参数的值,因为它们在编译时没有任何固定值。1

因此,最干净的方法可能是包装一个
resolve
调用
defn
,并调用结果函数——当然,为了确定,我们需要通过引入一个执行Var查找的宏来了解您试图解决的问题



1除非静态分配常量值,如问题文本中给出的示例;我假设您一般考虑使用局部变量的运行时值,而不仅仅是那些初始化表达式为常量文本的运行时值。

普通函数似乎更符合您的需要

不过,首先,为了解决最初的问题,如果您想坚持使用宏,宏是在编译时调用的常规函数,因此您可以使用变量的符号名查找变量,并使用
deref
获取其值,就像在(您的应用程序,而不是宏的)运行时一样:

请注意,上面的
1
是此处的实际宏扩展。这与

(defmacro var-value [vsym] @(resolve vsym))

(def foo 1)

(var-value foo)
;= 1
(macroexpand-1 '(var-value foo))
;= 1
后者扩展为调用
resolve
,因此给定实现的查找将推迟到应用程序的运行时

(defmacro var-value [vsym] `@(resolve ~vsym))
因此,无论在哪里调用宏,此代码都将被内联

当然,宏也可以扩展为符号–例如

(macroexpand-1 '(var-value foo))
;= (clojure.core/deref (clojure.core/resolve foo))
将生成扩展,如
v-1
(用于
(前缀为var1)
)等

回到这里的宏适用性主题,但是,如果使用宏,生成扩展所需的所有信息必须在编译时可用,因此,通常不能在扩展中使用
let
/
循环
局部变量或函数参数的值,因为它们在编译时没有任何固定值。1

因此,最干净的方法可能是包装一个
resolve
调用
defn
,并调用结果函数——当然,为了确定,我们需要通过引入一个执行Var查找的宏来了解您试图解决的问题



1除非静态分配常量值,如问题文本中给出的示例;我假设您一般考虑使用局部变量的运行时值,而不仅仅是那些初始化表达式为常量文本的值。

谢谢。还有一个问题,如果我有:(defmacro m[v]`(symbol(str“v-”~v)),那么:(让[i2](mi))可以得到一个“v-2 symbol”,可以得到这个值吗?再次感谢。所以,这个要求不能通过宏直接返回var的值(没有解析和var get等等),对吗?@jamesqiu AFAIK您必须以某种方式通过名称解析var,例如,
resolve
intern
clojure.lang.var/find
,等等,然后获取其值。请注意,
(defmacro[v]
@(resolve(symbol(str“v-”~v)))`只需扩展到
@(解析(symbol(str“v-”~v))
,即实际查找发生在运行时,代码在宏的调用程序中内联执行查找。这相当于在需要此模式的任何位置手动编写
@(解析…
)。更干净的解决方案将使用一个具有相同主体的函数减去语法quote+unquote。谢谢。还有一个问题,如果我有:(defmacro m[v]`(symbol(str“v-”~v)),那么:(让[i2](mi))可以得到一个“v-2 symbol”,可以得到这个值吗?再次感谢。所以,这个要求不能通过宏直接返回var的值(没有解析和var get等等),对吗?@jamesqiu AFAIK您必须以某种方式通过名称解析var,例如,
resolve
intern
clojure.lang.var/find
,等等,然后获取其值。请注意,
(defmacro[v]
@(resolve(symbol(str“v-”~v)))`只需扩展到
@(解析(symbol(str“v-”~v))
,即实际查找发生在运行时,代码在宏的调用程序中内联执行查找。这相当于在需要此模式的任何位置手动编写
@(解析…
)。更简洁的解决方案将使用一个具有相同主体的函数减去语法quote+unquote。