Clojure:列表中变量的名称
我有一个类似这样的想法:Clojure:列表中变量的名称,clojure,Clojure,我有一个类似这样的想法: (def a "text") (def b "text") (def c nil) (def d 8) (def e "") (def testlist (list a b c d e )) 现在,有没有办法得到变量名的字符串?我认为“不”是最可能的答案 似乎不起作用,因为它只返回值。列表是否仅包含def之后的值 编辑:我忘记了什么,这可能是这个问题的关键:我既不能使用eval也不能使用defmacro,两者都是不允许的(出于安全等原因)。因此,是的…您将无法从变量
(def a "text")
(def b "text")
(def c nil)
(def d 8)
(def e "")
(def testlist (list a b c d e ))
现在,有没有办法得到变量名的字符串?我认为“不”是最可能的答案
似乎不起作用,因为它只返回值。列表是否仅包含def之后的值
编辑:我忘记了什么,这可能是这个问题的关键:我既不能使用eval也不能使用defmacro,两者都是不允许的(出于安全等原因)。因此,是的…您将无法从变量名中获取字符串,因为Clojure将尽快对其求值,以生成
测试列表
=> (def testlist (a b c d e ))
("text" "text" nil 8 "")
但是,您可以选择检索与每个变量名关联的符号
=> (def testlist (quote (a b c d e ))) ;; equivalent to '(a b c d e ))
(a b c d e)
然后使用str
函数将这些符号转换为字符串
=> (map str testlist)
("a" "b" "c" "d" "e")
稍后,您可以eval
此列表来检索命名空间上下文中的值
=> (map eval testlist)
("text" "text" nil 8 "")
请注意,使用带有外部输入的eval
(例如读取行
)可以创建
此外,必须在与其定义相同的命名空间中对列表进行求值。否则,Clojure将无法解析符号
=> (ns otherns)
=> (map eval user/testlist)
java.lang.RuntimeException: Unable to resolve symbol: a in this context
大多数情况下的最佳实践是使用您将无法从变量名中获取字符串,因为Clojure将尽快对它们进行评估,以生成测试列表
=> (def testlist (a b c d e ))
("text" "text" nil 8 "")
但是,您可以选择检索与每个变量名关联的符号
=> (def testlist (quote (a b c d e ))) ;; equivalent to '(a b c d e ))
(a b c d e)
然后使用str
函数将这些符号转换为字符串
=> (map str testlist)
("a" "b" "c" "d" "e")
稍后,您可以eval
此列表来检索命名空间上下文中的值
=> (map eval testlist)
("text" "text" nil 8 "")
请注意,使用带有外部输入的eval
(例如读取行
)可以创建
此外,必须在与其定义相同的命名空间中对列表进行求值。否则,Clojure将无法解析符号
=> (ns otherns)
=> (map eval user/testlist)
java.lang.RuntimeException: Unable to resolve symbol: a in this context
在大多数情况下,最好的做法是使用虽然不清楚您想要实现什么,但仍然有一种可能的方法
meta
函数获取一个引用并返回一个带有:name
字段的映射,该字段包含一个带有变量名的sting:
user=> (def foo 42)
#'user/foo
user=> (meta #'foo)
{:line 1, :column 1,
:file "/some/tmp/file.clj",
:name foo,
:ns #namespace[user]}
现在还不清楚你想要实现什么,但仍然有一个可能的方法
meta
函数获取一个引用并返回一个带有:name
字段的映射,该字段包含一个带有变量名的sting:
user=> (def foo 42)
#'user/foo
user=> (meta #'foo)
{:line 1, :column 1,
:file "/some/tmp/file.clj",
:name foo,
:ns #namespace[user]}
您可以使用宏来实现这一点(只是为了好玩。我认为这根本不是一个可行的用例)
您可以使用宏来实现这一点(只是为了好玩。我认为这根本不是一个可行的用例)
这是一个猜测:我不知道clojure。但我怀疑您是在按值创建列表,因此列表只包含值,而不包含变量的引用。您可以构建符号列表:(list'a'b'c'd'e)
或vars:(list'a'b'c'd'e)
。您确实需要一个宏来完成此操作,通常在人们想要完成此操作时,原因不是很有说服力,而且几乎总是不是一个好主意。@Josh原因是,我想检查nil和empty,然后输出这些变量的名称。我的想法是,我不知道这个列表中有多少个元素,只是每个元素都会被检查并返回一个结果。@Kris是的,我可以,我只是在寻找一种懒散的方法来避免这样做。这是一个猜测:我不知道clojure。但我怀疑您是在按值创建列表,因此列表只包含值,而不包含变量的引用。您可以构建符号列表:(list'a'b'c'd'e)
或vars:(list'a'b'c'd'e)
。您确实需要一个宏来完成此操作,通常在人们想要完成此操作时,原因不是很有说服力,而且几乎总是不是一个好主意。@Josh原因是,我想检查nil和empty,然后输出这些变量的名称。我的想法是,我不知道这个列表中有多少个元素,只是每个元素都会被检查并返回一个结果。@Kris是的,我可以,我只是在寻找一种懒散的方法来避免这样做。