8.3 超越简单的分发
定义一个打印集合的方法实现:
(use '[clojure.contrib.str-utils :only (str-join)])
(defmethod my-print java.util.Collection [c]
(.write *out* "(")
(.write *out* (str-join " " c))
(.write *out* ")”))
尝试打印各种序列:
(my-println (take 6 (cycle [1 2 3])))
输出:(1 2 3 1 2 3)
(my-println [1 2 3])
输出:(1 2 3)
该方法很好,但打印向量时,不能像向量的定义那样,用方括号将输出包围。因此需要在添加一个实现方法,因为所有向量都实现IPersistentVector,因此可以这样定义该实现方法:
(defmethod my-print clojure.lang.IPersistentVector [c]
(.write *out* "[")
(.write *out* (str-join " " c))
(.write *out* "]"))
但是它不能正常工作,而是抛出异常:
(my-println [1 2 3])
java.lang.IllegalArgumentException: Multiplemethodsmatch
dispatch value: class clojure.lang.LazilyPersistentVector->
interface clojure.lang.IPersistentVectorand
interface java.util.Collection,
and neither ispreferred
问题是现在有两个dispatch值与向量匹配,Collection和IPersistentVector。很多语言限制方法分发来保证这种冲突不会出现,如禁止多继承。Clojure采用一种不同的方法来处理,允许出现冲突,然后通过prefer-method来解决:
(prefer-method multi-name loved-dispatch dissed-dispatch)
当你调用prefer-method的时候,你在告诉它匹配loved-dispatch值胜过dissed-dispatch值,不管是否有冲突。
因此针对上面的问题,我们可以告诉多重方法my-print你更喜欢IPersistentVector:
(prefer-method my-print clojue.lang.IPersistentVector java.util.Collection)
这时,你可以得到你想要的结果了:
(my-println (take 6 (cycle [1 2 3])))
输出:(1 2 3 1 2 3)
(my-println [1 2 3])
输出: [1 2 3]
定义一个打印集合的方法实现:
(use '[clojure.contrib.str-utils :only (str-join)])
(defmethod my-print java.util.Collection [c]
(.write *out* "(")
(.write *out* (str-join " " c))
(.write *out* ")”))
尝试打印各种序列:
(my-println (take 6 (cycle [1 2 3])))
输出:(1 2 3 1 2 3)
(my-println [1 2 3])
输出:(1 2 3)
该方法很好,但打印向量时,不能像向量的定义那样,用方括号将输出包围。因此需要在添加一个实现方法,因为所有向量都实现IPersistentVector,因此可以这样定义该实现方法:
(defmethod my-print clojure.lang.IPersistentVector [c]
(.write *out* "[")
(.write *out* (str-join " " c))
(.write *out* "]"))
但是它不能正常工作,而是抛出异常:
(my-println [1 2 3])
java.lang.IllegalArgumentException: Multiplemethodsmatch
dispatch value: class clojure.lang.LazilyPersistentVector->
interface clojure.lang.IPersistentVectorand
interface java.util.Collection,
and neither ispreferred
问题是现在有两个dispatch值与向量匹配,Collection和IPersistentVector。很多语言限制方法分发来保证这种冲突不会出现,如禁止多继承。Clojure采用一种不同的方法来处理,允许出现冲突,然后通过prefer-method来解决:
(prefer-method multi-name loved-dispatch dissed-dispatch)
当你调用prefer-method的时候,你在告诉它匹配loved-dispatch值胜过dissed-dispatch值,不管是否有冲突。
因此针对上面的问题,我们可以告诉多重方法my-print你更喜欢IPersistentVector:
(prefer-method my-print clojue.lang.IPersistentVector java.util.Collection)
这时,你可以得到你想要的结果了:
(my-println (take 6 (cycle [1 2 3])))
输出:(1 2 3 1 2 3)
(my-println [1 2 3])
输出: [1 2 3]