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

时间:2015-04-18 11:16:19

标签: clojure

我想在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)数据库与假数据,我在变量中手动编写,我想跟踪我的变量最终没有编写太多代码。

1 个答案:

答案 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