可以将协议扩展到原始数组,但指定类型类稍微有点复杂
(defprotocol P (p [_])) (extend-protocol P (Class/forName "[B") (p [_] "bytes")) (p (byte-array 0)) ;; => "bytes"
然而,如果您尝试做这些操作中的任何一个,事情就会变糟糕
`
(extend-protocol P
(Class/forName "[B") (p [_] "bytes")
(Class/forName "[I") (p [_] "ints"))
出现编译器异常:java.lang.UnsupportedOperationException: nth 不支持此类型:Character,编译于:(NO_SOURCE_PATH:1:1)
clojure.lang.Compiler.analyze (Compiler.java:6380)
clojure.lang.Compiler.analyze (Compiler.java:6322)
clojure.lang.Compiler$MapExpr.parse (Compiler.java:2879)
clojure.lang.Compiler.analyze (Compiler.java:6369)
clojure.lang.Compiler.analyze (Compiler.java:6322)
clojure.lang.Compiler$InvokeExpr.parse (Compiler.java:3624)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6562)
clojure.lang.Compiler.analyze (Compiler.java:6361)
clojure.lang.Compiler.analyze (Compiler.java:6322)
clojure.lang.Compiler$BodyExpr$Parser.parse (Compiler.java:5708)
clojure.lang.Compiler$FnMethod.parse (Compiler.java:5139)
clojure.lang.Compiler$FnExpr.parse (Compiler.java:3751)
原因
UnsupportedOperationException nth 不支持此类型:Character
clojure.lang.RT.nthFrom (RT.java:857)
clojure.lang.RT.nth (RT.java:807)
clojure.core/emit-hinted-impl/hint--5951/fn--5953 (core_deftype.clj:758)
clojure.core/map/fn--4207 (core.clj:2487)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:60)
clojure.lang.RT.seq (RT.java:484)
clojure.lang.RT.countFrom (RT.java:537)
clojure.lang.RT.count (RT.java:530)
clojure.lang.Cons.count (Cons.java:49)
clojure.lang.Compiler.analyze (Compiler.java:6352)
clojure.lang.Compiler.analyze (Compiler.java:6322)
`
在 {parse-impls} 中的代码将第二个 {(Class/forName "[I")} 视为一个函数,而不是一个新类型。一种解决方案是一次只扩展协议到一个类型。
如果这里有一种语法可以指定原始数组类型,那就更好了(进入增强领域)。我们已经有了类似 {bytes, ints, longs} 等用于类型提示的语法,这对我来说似乎是完美的。