如何获得使用let定义的局部变量的映射?
(let [foo 1] (println (get (get-thread-bindings) "foo")))
; prints nil
Run Code Online (Sandbox Code Playgroud)
还有其他功能吗?或者有没有办法从get-thread-bindings映射中提取变量?任何解决方案也应该与嵌套的let语句一起使用.
正如评论中的链接所指出的那样,里面有一个特殊的&env变量defmacro.根据文件:
defmacro中有两个特殊变量可用于更高级的用法:
- &form - 正在调用的实际表单(作为数据)
- &env - 宏扩展点的本地绑定映射.env映射是从符号到包含有关该绑定的编译器信息的对象.
您可以使用它来编写将扩展的宏,以便在扩展宏的位置为您提供本地绑定的映射:
(defmacro get-env
[]
(into {} (for [k (keys &env)]
[(name k) k])))
Run Code Online (Sandbox Code Playgroud)
这将作为符号名称的映射扩展为所有本地绑定的(name k)符号,在评估时,它将为符号的当前绑定提供符号名称的映射.k(keys &env)
user> (get-env) ; => {}
user> (let [a 1] (get-env)) ; => {"a" 1}
user> (let [a 1 b 2]
(let [b 3 c 4] (get-env))) ; => {"c" 4, "b" 3, "a" 1}
Run Code Online (Sandbox Code Playgroud)
它甚至可以使用函数参数:
user> (defn foo [x] (let [y 1] (get-env)))
user> (foo 2) ; => {"y" 1, "x" 2}
Run Code Online (Sandbox Code Playgroud)