如何从变量或函数中获取名称字符串?

how to get the name string from a variable or function?

我想在 Clojure 中以字符串形式获取变量名。 但是,与 this question 不同的是,我会得到原始绑定的名称(不确定术语是否正确,请参阅下面的示例)。

(def sample-data1 {:data 1})
(def sample-data2 {:data 2})
(def sample-data3 {:data 3})


(doseq
    [my-var [sample-data1 sample-data2 sample-data3]]
  (println (name 'my-var)))

在这种情况下,而不是打印

my-var
my-var
my-var

我想要:

sample-data1
sample-data2
sample-data3

我如何在 Clojure 中做到这一点?

注意:这可能不是在真实应用程序中做的最漂亮的事情。但我的问题是这是否可能。

澄清一下:这是为了制作原型。在这个特定的例子中,我没有打印,而是用我在变量中手写的假数据填充了一个(postgres)数据库,我想跟踪我的变量在哪里结束而不写太多代码。

def 创建一个与作为 def 第一个参数提供的符号名称同名的变量。 Clojure 中的 Var 不同于我们通常所说的变量,而变量通常可以可视化为包含值的框,而 var 是指向值的东西。

根据你的例子,(在这里,我在 user 命名空间中)

user> (def sample-data1 {:data 1})
#'user/sample-data1

clojure 在 user 命名空间中创建一个指向 {:data 1} 值的 #'user/sample-data1 变量。您可以通过使用 deref@ shorthand.

取消引用它来从新创建的 var 中取回值
user> (deref #'user/sample-data1)
{:data 1}
user> @#'user/sample-data1
{:data 1}

或者如果您评估一个符号,clojure 会在当前命名空间中查找一个 var 和 returns 该 var 指向的值。

user> sample-data1
{:data 1}

您可以通过使用 var for #' shorthand.

从符号中获取 var
user> (var sample-data1)
#'user/sample-data1
user> #'sample-data1
#'user/sample-data1

因此,您需要变量的名称。 var 的名称包含在 var 的元数据中,可以使用应用于 var 的 meta 来访问。

user> (meta #'sample-data1)
{:line 1, :column 1, :file "/tmp/form-init3246148490151701909.clj",
 :name sample-data1, :ns #object[clojure.lang.Namespace 0x39ba2c26 "user"]}

上面,你可以看到var的名字是通过:name键定位的。

因此,您可以从其元数据中获取变量的名称。

user=> (:name (meta #'sample-data1))
sample-data1

我不想有太多的嵌套括号,所以我使用线程优先宏->

user=> (-> #'sample-data1 meta :name)
sample-data1

答案

所以回到你的问题,你需要 sample-data[1-3] 变量和它们的元数据来获得它们的名字。

(def sample-data1 {:data 1})
(def sample-data2 {:data 2})
(def sample-data3 {:data 3})

(doseq
    [my-var [#'sample-data1 (var sample-data2) #'sample-data3]] 
  (println (-> my-var meta :name)))

结果是

sample-data1
sample-data2
sample-data3
nil