我想在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)数据库与假数据,我在变量中手动编写,我想跟踪我的变量最终没有编写太多代码。
答案 0 :(得分:6)
def
创建一个var,其名称与作为def
第一个参数提供的符号名称相同。 clojure中的var与我们通常用变量的含义不同,而变量通常可以被视为包含值的框,而var是指向值的内容。
从您的示例中,(此处,我在user
命名空间中)
user> (def sample-data1 {:data 1})
#'user/sample-data1
clojure在#'user/sample-data1
命名空间中创建user
var,指向{:data 1}
值。您可以通过使用deref
或@
简写来解析它,从新创建的var中获取值。
user> (deref #'user/sample-data1)
{:data 1}
user> @#'user/sample-data1
{:data 1}
或者如果你评估一个符号,clojure会在当前命名空间中查找var并返回该var指向的值。
user> sample-data1
{:data 1}
您可以使用var
获取#'
的简写,从符号中获取变量。
user> (var sample-data1)
#'user/sample-data1
user> #'sample-data1
#'user/sample-data1
所以,你想要var的名字。 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
键。
因此,您可以从其元数据中获取var的名称。
user=> (:name (meta #'sample-data1))
sample-data1
我不希望有太多嵌套的括号,所以我使用线程优先宏->
user=> (-> #'sample-data1 meta :name)
sample-data1
回到你的问题,你需要sample-data[1-3]
vars及其元数据来获取他们的名字。
(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