如何从变量或函数中获取名称字符串?
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
我想在 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.
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.
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