作为其分派的一部分,编写修改传入参数的multimethod的惯用方法是什么?
在这种情况下,我想删除其中一个论点:
(defmulti do-update ???)
(defmethod do-update :set-cursor [state x y]
(assoc state :cursor [x y]))
(defn post [action & args]
(swap! some-state do-update action args))
(post :set-cursor 0 0)这里的dispatch-fn将负责读取action关键字,并将(cons state args)作为方法的参数转发。
这种方法的另一种选择是创建调度图。
(defn set-cursor [state x y])
(def handlers
{:set-cursor set-cursor})
(defn dispatch [action & args]
(let [handler (action handlers)]
(apply swap! some-state handler args)))但是在没有映射的情况下,根据相应的操作自动注册这些处理程序将是很好的。
发布于 2018-07-26 02:17:22
作为多方法设计的一部分,这些方法接收与调度函数相同的参数。如果这些方法对仅用于分派的某些参数不感兴趣,那么在方法实现中忽略它们是非常好的--而且一点也不奇怪:
(def some-state (atom {:cursor [-1 -1]}))
(defmulti do-update
(fn [state action x y]
action))
;; ignoring the action argument here:
(defmethod do-update :set-cursor [state _ x y]
(assoc state :cursor [x y]))
;; added apply here to avoid ArityException in the call to do-update:
(defn post [action & args]
(apply swap! some-state do-update action args))
(post :set-cursor 0 0)
@some-state
;= {:cursor [0 0]}请注意,为了方便do-update与swap!的使用,调度参数位于第二位。
发布于 2018-07-26 01:02:05
您不能直接询问该方法是什么输入到调度函数,从而导致它选择调用此方法,这是可以的,因为调度方法只是函数!
您可以在分派给它的方法中再次调用调度函数。只要您的调度函数是纯函数,这将是坚实的。如果不是..。
因此,如果您将yoru yes函数定义为??? (是的?)是有效的函数名)
user=> (defn ??? [x] (inc x))
#'user/???你的多重方法是这样的
user=> (defmulti foo ???)然后在方法中再次调用调度函数:
(defmethod foo 1 [x]
(str "I was dispatched from " x
" and i will use " (??? x)
" to do my good work"))您可以重构调度函数的操作,而不必维护一个独立的函数/map/thing。
user=> (foo 0)
"I was dispatched from 0 and i will use 1 to do my good work"发布于 2018-07-26 02:14:49
虽然核心语言不支持这一点,但您可以使用一些“重写”宏来对所需的语义进行分层:
(defmacro defupdatemulti [name]
`(defmulti ~name (fn [state# action# & args#] action#)))
(defmacro defupdatemethod [name action [state & args] & body]
`(defmethod ~name ~action
[~state _# [~@args]]
~@body))并利用这一点:
(defupdatemulti do-update)
(defupdatemethod do-update :set-cursor [state x y]
(assoc state :cursor [x y]))在此基础上
(def some-state (atom {}))
(defn post [action & args]
(swap! some-state do-update action args))
(post :set-cursor 0 0)产生的结果如下:
{:cursor [0 0]}注:虽然上面的工作,它肯定不是惯用的。
https://stackoverflow.com/questions/51528140
复制相似问题