2016-03-16 60 views
1

我似乎很難理解下面的代碼是如何工作的。更確切地說,是如何定義的函數處理傳遞的參數定義的「遭遇」時Clojure定義多方法以及如何傳遞參數

(defmulti encounter 
    (fn [x y] [(:role x) (:role y)])) 

(defmethod encounter [:manager :boss] [x y] 
    :promise-unrealistic-deadlines) 

(defmethod encounter [:manager :developer] [x y] 
    :demand-overtime) 
.... 

爲什麼我們有2個向量([x y] [(:role x) (:role y)])。這是否意味着函數需要向量參數?如果是這樣,爲什麼我要調用的功能等:

(encounter {:role :manager} {:role :boss})

不是上述呼叫經過第一HashMap來[xy]或第二至[(:角色X)(:角色Y) ])。我只是不明白如何x得到價值:經理和y得到的價值:老闆。

上面的例子是從這裏:https://yogthos.github.io/ClojureDistilled.html

回答

5

傳遞給defmulti宏的第二個參數被稱爲調度功能。在這裏,它接受兩個參數,xy,其中每個參數預計都是帶有:role鍵的地圖。調度函數返回的值稱爲調度值。正在與您撥打encounter時進行比較。

encounter方法的每個定義都將一些分派值作爲其第二個參數。在您的示例中,該值是通過將參數xy傳遞到defmulti內的調度函數(fn [x y] [(:role x) (:role y)])中生成的。根據由該函數返回的值,或者是相應的方法被調用,或IllegalArgumentException拋出:

(encounter {:role :designer} {:role :developer}) 

產生

IllegalArgumentException No method in multimethod 'encounter' for dispatch value: [:designer :developer] clojure.lang.MultiFn.getFn (MultiFn.java:156) 

但是增加一個新的可能的調度值修復它:

(defmethod encounter [:designer :developer] [x y] 
    :discuss-video-games) 

(encounter {:role :designer} {:role :developer}) 
=> :discuss-video-games 

還有一個dedicated clojuredocs page更多的好例子。