我似乎很难理解下面的代码是如何工作的。更确切地说,定义的函数如何处理传递的参数
(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传递给[x y]而第二个传递给[(:role x)(:role y)])。我无法理解 x 如何获得价值:经理和 y 获得价值:老板。
答案 0 :(得分:5)
传递给defmulti
宏的第二个参数称为调度函数。在这里,它接受两个参数x
和y
,每个参数都应该是一个带有:role
键的地图。 dispatch函数返回的值称为dispatch值。无论何时拨打encounter
,都会对其进行比较。
encounter
方法的每个定义都将一些调度值作为其第二个参数。在您的示例中,通过将参数x
和y
传递到(fn [x y] [(:role x) (:role y)])
内的调度函数defmulti
来生成该值。根据该函数返回的值,调用相应的方法,或抛出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有更好的例子。