2016-08-20 60 views
0

我是clojure的新手。我想使用Clojure中的報價方式如下:如何在clojure中引用參數

首先,我定義一個變量:

(DEF狗 「動物」)

然後一個功能::

(定義什麼是[名稱]

('name(str「是一個」名稱)))

如果我調用該函數什麼,是與可變作爲參數: (什麼 - 是狗)

結果應該是:

USER >>狗動物

在這裏,我回到我傳遞給函數什麼,是,而不是其價值的參數的名稱:

我得到的卻是:

是動物

沒有提到的參數這裏的。

再次什麼我找的就是重複「字面意思是」我傳遞給函數,這個模板參數的名稱:

(乜爲x)=> x是..

謝謝。

回答

4

這不是你可以用函數做的事情。一個函數只接收運行時值,而不是被評估生成這些值的代碼。如果你想定義的一段代碼,使得實際使用中的源代碼,而不是運行時的值,你可以使用一個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" 
+0

謝謝@Sam Estep。這就是我要找的。 – omar

+0

爲什麼一個引用的運算符像'('name 5); ==> nil'在Clojure中工作? – Sylwester

+0

@Sylwester是;請參閱我對[此問題]的回答(http://stackoverflow.com/q/35541931/5044950)。 'Symbol'類提供['invoke']的實現(https://github.com/clojure/clojure/blob/clojure-1.8.0/src/jvm/clojure/lang/Symbol.java#L125-L127 )相當於['get'](https://clojuredocs.org/clojure.core/get)。 –

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" 

還有其他的,也許是更好的方法來寫這些功能,但我想保持基本的東西。

+0

@火星感謝您的回答。你期待着另一件我想實現的事情:對事物有多種定義。所以地圖是最好的數據結構。 – omar

+0

@ Mars有沒有一種方法可以將函數調用的是參數,而不是以字符串的形式傳遞。什麼是狗,而不是什麼是「狗」?再次感謝 – omar

+0

Omar,因爲你需要一個宏,就像Sam Estep的回答一樣。然而,通常使用關鍵字,例如':dog'作爲地圖的關鍵字,而不是字符串或其他對象。在我的例子中,我只使用字符串作爲鍵,因爲我不想一次性將太多東西扔進答案。通常情況下,我會使用'{:狗「動物」:貓「動物」等等,或者「{:狗:動物:貓:動物...}」或類似的東西,就像我的地圖一樣。 – Mars