我已经在很多Clojure代码中读取了模式(defmulti multi (fn [t] (cond (seq? t) :seq (map? t) :map (vec? t) :vec ...
,它基本上是一个开关(如果我添加一个类型,我必须添加一个新子句)但更详细。有没有办法说(defmethod seq, (defmethod vec (defmethod map..
等?这一定是很常见的事情。我知道可以手动定义层次结构,但是对于常见的Clojure类型,如sequence,vector,map ......,是否必须为每个在类型上调度的程序定义?请告诉我,我错过了这一点!
编辑:好吧我以为我可以说(defmulti mymulti type)
然后(defmethod clojure.lang.PeristantSomething...
等等,但是这很笨拙,因为它引用了java类,但我想引用一些'类型'的质量,比如它是否是顺序或关联
答案 0 :(得分:3)
在类型上调度适用于此:
user> (import '[clojure.lang Associative Sequential])
user> (defmulti foo type)
#'user/foo
user> (defmethod foo Associative [x] :map)
#<MultiFn clojure.lang.MultiFn@7e69a380>
user> (foo {:x 1})
:map
user> (foo ())
; fails, a list is not associative
user> (defmethod foo Sequential [x] :seq)
#<MultiFn clojure.lang.MultiFn@7e69a380>
user> (foo ())
:seq
user> (foo [])
; fails, a vector is both sequential and associative
user> (prefer-method foo Sequential Associative)
#<MultiFn clojure.lang.MultiFn@7e69a380>
user> (foo [])
:seq
请注意,Sequential和Associative都是接口而不是具体类。
答案 1 :(得分:0)
选择调度函数是类型或类。