我是clojure的新手。我想用以下方式在clojure中使用引用:
首先我定义一个变量:
(def dog“animal”)
然后是一个函数::
(定义什么是[姓名]
('name(str“是”名称)))
如果我使用变量 dog 作为参数调用函数 what-is : (什么是狗)
结果应为:
使用者>>狗是动物
这里我返回了传递给函数 what-is 的参数的名称,而不是它的值:
我得到的是:
是动物
此处未提及参数 dog 。
我正在寻找的是重复“字面上”我传递函数的参数的名称,如在此模板中:
(what-is x)=> x是......
谢谢。
答案 0 :(得分:5)
这不是您可以使用函数执行的操作。函数只接收运行时值,而不是为了生成这些值而被评估的代码。如果要定义一段使用实际源代码而不是运行时值的代码,可以使用macro:
(defmacro what-is [x]
`(str '~x " is an " ~x))
(what-is dog)
;;=> "dog is an animal"
如您所见,此what-is
宏与您的what-is
功能不同;它利用了Clojure的语法报价阅读器宏。不是在运行时使用字符串作为输入调用并返回字符串作为输出,而是在编译时使用一段代码(x
)在编译时调用此宏,并返回另一段代码,然后将返回被评估。您可以使用macroexpand-1
函数查看what-is
宏返回的确切代码:
(macroexpand-1 '(what-is dog))
;;=> (clojure.core/str (quote dog) " is an " dog)
如果需要,您可以评估这段扩展的代码,看它是否给出了相同的结果:
(clojure.core/str (quote dog) " is an " dog)
;;=> "dog is an animal"
答案 1 :(得分:2)
这是另一种做我认为你想做的事情的方法。不要将变量的类别定义为其值,而是使用Clojure映射。例如,使用基本的{}
映射语法:
(def what-is-map {"dog" "animal"
"cat" "animal"
"Fiat" "auto"
"flu" "illness"})
(defn what-is [thing]
(str thing " is an " (what-is-map thing)))
最后一个表达式有效,因为在许多情况下,地图可以像函数一样使用。
(what-is "dog") ;=> "dog is an animal"
(what-is "flu") ;=> "flu is an illness"
您还可以为地图中没有的内容提供默认值。这是一种方式:
(defn what-is [thing]
(let [what-it-is (what-is-map thing)]
(if what-it-is
(str thing " is a " what-it-is)
(str "I don't know what a " thing " is"))))
if
有效,因为在地图中找不到某个键时,会返回nil
。 (nil
是错误值之一。另一个是false
。)
(what-is "fish") ;=> I don't know what a fish is"
还有其他可能更好的方法来编写这些函数,但我想保持基本的东西。