Clojure 定义多方法以及如何传递参数
Clojure defining multimethods and how to pass parameters
我似乎很难理解下面的代码是如何工作的。更准确地说,定义的函数如何处理传递的参数
(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)
....
为什么我们在定义 "encounter" 时有 2 个向量 ([x y] [(:role x) (:role y)]
)。这是否意味着该函数采用矢量参数?如果是这样,为什么我必须像这样调用函数:
(encounter {:role :manager} {:role :boss})
上面的调用不是将第一个 hashmap 传递给 [x y],将第二个传递给 [(:role x) (:role y)])。我只是不明白 x 是如何获取 :manager 的值,而 y 是如何获取 :boss.
的值的
传递给 defmulti
宏的第二个参数称为调度函数。在这里,它接受两个参数,x
和 y
,每个参数都应该是一个包含 :role
键的映射。调度函数返回的值称为调度值。每当您调用 encounter
.
时,都会将其与它进行比较
encounter
方法的每个定义都将一些调度值作为其第二个参数。在您的示例中,该值是通过将参数 x
和 y
传递到 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 有更多好的例子。
我似乎很难理解下面的代码是如何工作的。更准确地说,定义的函数如何处理传递的参数
(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)
....
为什么我们在定义 "encounter" 时有 2 个向量 ([x y] [(:role x) (:role y)]
)。这是否意味着该函数采用矢量参数?如果是这样,为什么我必须像这样调用函数:
(encounter {:role :manager} {:role :boss})
上面的调用不是将第一个 hashmap 传递给 [x y],将第二个传递给 [(:role x) (:role y)])。我只是不明白 x 是如何获取 :manager 的值,而 y 是如何获取 :boss.
的值的传递给 defmulti
宏的第二个参数称为调度函数。在这里,它接受两个参数,x
和 y
,每个参数都应该是一个包含 :role
键的映射。调度函数返回的值称为调度值。每当您调用 encounter
.
encounter
方法的每个定义都将一些调度值作为其第二个参数。在您的示例中,该值是通过将参数 x
和 y
传递到 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 有更多好的例子。