将Clojure协议扩展为原始数组

mik*_*era 5 arrays protocols clojure primitive-types

我想扩展一个Clojure协议来处理Java原始数组.

(defprotocol PVectorisable
  (to-vector [a]))

(extend-protocol PVectorisable
  ??????
    (to-vector [coll]
      (Vectorz/create ^doubles coll))
  java.util.List
    ... other implementations......)
Run Code Online (Sandbox Code Playgroud)

这是可能的,如果是这样,上面的扩展协议定义需要进行什么(代替"??????")?

Bey*_*mor 9

最简单的解决方案可能是用反射以编程方式抓取类.

(defprotocol do-a-thing
 (print-thing [thing]))

(extend-protocol do-a-thing
 (class (float-array 0))
  (print-thing [_]
   (println "it's a float array")))
Run Code Online (Sandbox Code Playgroud)

Java的数组有些奇怪的名字.例如,浮点数组是[F.如果你试图直接在REPL中使用它,它会扼杀在无与伦比的[.但是,您仍然可以使用此名称,例如Class/forName.

(defprotocol do-another-thing
 (print-another-thing [thing]))

(extend-protocol do-another-thing
 (Class/forName "[F")
  (print-another-thing [_]
   (println "it's still a float array")))
Run Code Online (Sandbox Code Playgroud)

本文将详细介绍数组类.

  • 我发现这只有在它是扩展协议定义中的第一个类时才有效.如果没有,Clojure 1.5.1给出了一个java.lang.UnsupportedOperationException,并抱怨在Character或Symbol类型上不支持第n个. (7认同)