如何引用clojure中的参数

时间:2016-08-20 00:40:50

标签: clojure arguments quote

我是clojure的新手。我想用以下方式在clojure中使用引用:

首先我定义一个变量:

  

(def dog“animal”)

然后是一个函数::

  

(定义什么是[姓名]

     

('name(str“是”名称)))

如果我使用变量 dog 作为参数调用函数 what-is : (什么是狗)

结果应为:

使用者>>狗是动物

这里我返回了传递给函数 what-is 的参数的名称,而不是它的值:

我得到的是:

  

是动物

此处未提及参数 dog

我正在寻找的是重复“字面上”我传递函数的参数的名称,如在此模板中:

  

(what-is x)=> x是......

谢谢。

2 个答案:

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

还有其他可能更好的方法来编写这些函数,但我想保持基本的东西。