gpt4 book ai didi

clojure - 如何在 Clojure 中获取参数名称?

转载 作者:行者123 更新时间:2023-12-02 17:43:38 25 4
gpt4 key购买 nike

我想从函数内部获取函数外部定义的 var 的名称。该名称应该是我在原始定义范围内使用的名称,而不是我实际尝试使用该名称的任何嵌套绑定(bind)。

所以我想做一些类似的事情(学术示例):

(defn f1 [x1] (println "hello, you passed var name >>" (get-var-name x1) "<<")
(defn f2 [x2] (f1 x2))
(defn f3 [x3] (let [zzz x3] (f2 zzz))
(def my-var 3.1414926)
(f3 my-var)
user> hello, you passed var name >>my-var<<

我可以根据我发现的一些东西来执行这个宏:

(defmacro get-var-name [x]
`(:name (meta (var ~x))))

这在从 REPL 调用时有效,但在从“内部”范围调用时编译器会阻塞,例如

(defn another-func [y]
(get-var-name y))

编译器显示“无法解析 var y”。 (macroexpand...) 显示它正在尝试在当前命名空间中查找局部变量 y,而不是当前命名空间中的原始变量。我认为 (var...) 只查找命名空间变量,因此这会阻止宏在函数或另一个绑定(bind)(例如 let)中工作。

认为我不得不从定义变量的同一范围手动获取变量名称并将其作为额外参数传递。是否有一种更优雅的方法来通过绑定(bind)链将 var 名称信息传递到使用它的地方?那可就太糟糕了。

谢谢

最佳答案

不可能获取函数内外部作用域中使用的 var 的名称 - 该函数仅接收在运行时作为参数传递的,不是变量本身。

您唯一可以做的就是在每个级别使用宏而不是函数。这允许您在编译时通过不同的宏传递 var 本身:

(defmacro f1 [x1] `(println "hello, you passed var name >>" ~(str x1) "<<"))
(defmacro f2 [x2] `(f1 ~x2))
(defmacro f3 [x3] (let [zzz x3] `(f2 ~zzz)))

(f3 my-var)
=> hello, you passed var name >> my-var <<

这非常难看 - 您当然不希望仅仅为了获得此功能而使用宏编写所有代码!尽管在某些特殊情况下这可能是有意义的,例如如果您正在创建某种基于宏的 DSL。

关于clojure - 如何在 Clojure 中获取参数名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11856517/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com