2012-10-13 74 views
14

我想知道爲什麼使用defmulti & defmethod? 有什麼優勢? 你如何使用它?請解釋代碼中發生了什麼。如何以及爲什麼使用defmulti和defmethod?有什麼優勢?

+0

是你能夠定義多方法是什麼?如果沒有,那麼我會很高興來解釋你 – tgoossens

+0

這是一個問題,我曾經問:http://cs.stackexchange.com/questions/4660/difference-between-multimethods-and-overloading 我回答我自己的問題此外,這可能會幫助您瞭解多方法是什麼 – tgoossens

回答

25

在「一般條款」,你會叫它的if/else類固醇和「打動我」的風格,你會用「動態調度」,「運行時多態性」等

命名,讓我們看看定義一個函數「Add」,它應該適用於各種數據類型,比如在Int情況下它應該添加數字,如果是字符串,它應該串聯字符串。現在使用if來實現它非常簡單,基本上你可以檢查參數的類型,如果它們是整數,那麼添加它們,如果它們是字符串,那麼將它們連接起來,否則會拋出異常。但問題在於,如果您希望在添加功能中添加對新數據類型的支持,您將需要修改添加功能,這在您無法控制添加源的情況下可能無法實現例如在某些庫中定義的情況等。 defmultidefmethod允許您解決此問題,即向現有函數添加新案例而不修改其代碼。

(defmulti add (fn [a b] [(type a) (type b)]))

補充的是函數名,匿名函數是你的if/else,基本上將其稱爲在你的附加參數,如果有任何實現這個函數的返回值將被檢查。現在我們來實現Integer。

(defmethod add [Integer Integer] ([a b] (+ a b)))

[Integer Integer]對我們defmulti定義的匿名函數,然後執行的返回值類型的切換情況。

同樣,我們可以爲字符串

(defmethod add [String String] ([a b] (str a b)))

與整數 (add (int 1) (int 2))

用繩子 (add "hello" "world")

的東西,不符合調用它調用它稱它做我們如果/否則即不執行一個案件將導致例外

+2

非常感謝!這非常有幫助! – Phil

+0

謝謝你的解釋! – goncalvesnelson

7

從我讀了答案(使用上述示例)後觀察到的東西,下面也有助於理解:

當你執行命令:

(add (int 5) (int 2)) 

會發生什麼事該「添加defmulti」從而執行產生的列表:

[Integer Integer] 

與生產時,它查找任何「添加defmethod」被識別與上面所列內容即:

(add [Integer Integer]) 

並傳遞它收到的參數。

定義多方法,使論點明確傳遞的另一種方法是:

(defmulti add (fn [a b] [(type a) (type b)])) 
(defmethod add [Integer Integer] [a b] (+ a b)) 
(defmethod add [String String] [a b] (str a b)) 

然後運行功能:

(add 12 73) 

(add "thank" "you") 
相關問題