如果您尝试运行以下代码,您会看到它将进行编译,但在运行时的倒数第二行由于"没有为类型cljs.core/PersistentArrayMap:{}定义协议方法NameSayer.say-name"而失败,即使它满足?调用返回true。IVector/PersistentVector情况也会出现类似的故障,尽管也满足所需的协议。
(defprotocol NameSayer
(say-name [input]))
(extend-protocol NameSayer
number
(say-name [_]
"I'm a number!")
string
(say-name [_]
"I'm a string!")
IMap
(say-name [_]
"I'm a map!")
IVector
(say-name [_]
"I'm a vector!"))
(println (satisfies? IMap {}))
(println (satisfies? IVector []))
(println (say-name "hello"))
(println (say-name 100))
(println (say-name {}]))
(println (say-name []))
我在clojuescription.core中窥探了一下,发现对于像IPrintWithWriter这样的东西,PersistentArrayMap、PersistentHashMap和PersistentTreeMap的实现只是重复的,尽管它们都有通用的IMap接口。有没有比使用协议进行代码复制更好的方法来解决这个问题?
来自clojurians线程的关于同一主题的一些建议:
如果你控制协议-采取协议中的每一种方法,并将其从一种方法更改为另一种方法*
(defn method [o]
(cond
(satisfies? Proto o)
(method* o)
(map? o)
(map-impl o)
(set? o)
(set-impl o)
(sequential? o)
(sequential-impl o)
:else
(throw (ex-info "" {})))
如果性能对于您自己的协议来说不是很重要,那么您也可以通过default
进行即default
+satisifes?
等