如何在 Clojure 中引用参数
How to quote an argument in clojure
我是 Clojure 新手。我想通过以下方式在 clojure 中使用引号:
首先我定义一个变量:
(def dog "animal")
然后是函数::
(defn what-is [name]
('name (str " is an " name)))
如果我使用变量 dog 作为参数调用函数 what-is:
(什么是狗)
结果应该是:
USER>> 狗是一种动物
这里我返回了传递给函数what-is的参数名称,而不是它的值:
我得到的是:
is an animal
此处未提及参数 dog。
同样,我正在寻找的是重复 "literally" 我传递给函数的参数的名称,如在这个模板中:
(what-is x )=> x is an ...
谢谢。
这不是你可以用函数来做的事情。函数仅接收运行时值,而不是为生成这些值而计算的代码。如果你想定义一段使用实际源代码的代码,而不是运行时值,你可以使用 macro:
(defmacro what-is [x]
`(str '~x " is an " ~x))
(what-is dog)
;;=> "dog is an animal"
如您所见,这个 what-is
宏看起来与您的 what-is
函数不同;它利用了 Clojure 的 syntax-quote reader 宏。这个宏不是在运行时调用一个字符串作为输入并返回一个字符串作为输出,而是在编译时用一段代码 (x
) 在编译时调用,在另一段代码中调用 returns ,然后将对其进行评估。可以使用macroexpand-1
函数查看what-is
宏returns:
到底是什么代码
(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"
这里有另一种方法可以完成我认为您想做的事情。不要将变量的类别定义为其值,而是使用 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"
还有其他可能更好的方法来编写这些函数,但我想保持基本。
我是 Clojure 新手。我想通过以下方式在 clojure 中使用引号:
首先我定义一个变量:
(def dog "animal")
然后是函数::
(defn what-is [name]
('name (str " is an " name)))
如果我使用变量 dog 作为参数调用函数 what-is: (什么是狗)
结果应该是:
USER>> 狗是一种动物
这里我返回了传递给函数what-is的参数名称,而不是它的值:
我得到的是:
is an animal
此处未提及参数 dog。
同样,我正在寻找的是重复 "literally" 我传递给函数的参数的名称,如在这个模板中:
(what-is x )=> x is an ...
谢谢。
这不是你可以用函数来做的事情。函数仅接收运行时值,而不是为生成这些值而计算的代码。如果你想定义一段使用实际源代码的代码,而不是运行时值,你可以使用 macro:
(defmacro what-is [x]
`(str '~x " is an " ~x))
(what-is dog)
;;=> "dog is an animal"
如您所见,这个 what-is
宏看起来与您的 what-is
函数不同;它利用了 Clojure 的 syntax-quote reader 宏。这个宏不是在运行时调用一个字符串作为输入并返回一个字符串作为输出,而是在编译时用一段代码 (x
) 在编译时调用,在另一段代码中调用 returns ,然后将对其进行评估。可以使用macroexpand-1
函数查看what-is
宏returns:
(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"
这里有另一种方法可以完成我认为您想做的事情。不要将变量的类别定义为其值,而是使用 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"
还有其他可能更好的方法来编写这些函数,但我想保持基本。