【问题标题】:Clojure defining multimethods and how to pass parametersClojure 定义多方法以及如何传递参数
【发布时间】:2016-03-16 09:34:34
【问题描述】:

我似乎很难理解下面的代码是如何工作的。更确切地说,定义的函数如何处理传递的参数

(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 是如何获得 :manager 的价值,而 y 是如何获得 :boss 的价值的。

上面的例子来自这里:https://yogthos.github.io/ClojureDistilled.html

【问题讨论】:

    标签: clojure multimethod


    【解决方案1】:

    传递给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 有更多很好的例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多