Quelle est la meilleure façon de détecter si un objet est un tableau primitif Java dans le clojure?
La raison pour laquelle j'ai besoin de faire une manipulation spéciale pour les tableaux primitifs, ce qui pourrait ressembler à quelque chose comme: P>
(if (byte-array? object) (handle-byte-array object))
7 Réponses :
Vous pouvez utiliser la réflexion une fois pour obtenir la classe du nom, cache ceci puis Comparez le reste à celui
(def array-of-ints-type (Class/forName "[I")) (def array-of-bytes-type (Class/forName "[B")) ... (= (type (into-array Integer/TYPE [1 3 4])) array-of-ints-type) true
Nice, comme l'idée de mettre en cache les classes de la matrice primitives. Bien que cela me frappe comme un peu loin que ceux-ci ne sont pas déjà définis quelque part en Java!
"[j" code> pour
long code> s est encore plus attachant, n'est-ce pas? En outre, quiconque a proposé les supports d'ouverture inégalés dans
.tostring code> valeurs de retour, à tout moment, j'apprends leur nom, mon pitchfork sera prêt. Il brise Paredit pour moi tout le temps, sans parler L'effet sur ma psyche . (Remplacement de
PRINT-METHODE CODE> pour tous les cas pertinents peut être réalisable ou non - mon sentiment d'intestin en cours est pas i>.)
(defn long-array? [o] (let [c (class o)] (and (.isArray c) (identical? (.getComponentType c) Long/TYPE))))
Tous les secrets sont mis à nu: docs.oracle.com/ Javase / 6 / Docs / API / Java / Lang / Class.html
ou ancien instance code>:
Quel alias utilisez-vous pour rt code>? Vous voulez dire
(classe / forname "[b") code> non?
@Davidjames rt est clojure.lang.rt.
Comme indiqué par Arthur Ulfeldt, vous pouvez utiliser Si vous souhaitez éviter les chaînes magiques comme Classe / FORNAME CODE>, par exemple, comme ici:
"[B" code> Lors de la mise en cache des classes, vous pouvez appliquer
class code> à un objet de tableau existant: p>
Même plus simple: (classe d'octet-arrare-classe (classe (byte-array 0))) code>. (Pas de soulignement non plus!)
Pour vérifier un tableau d'octets sans utiliser de réflexion, vous pouvez le faire:
(def ^:const byte-array-type (type (byte-array 0))) (defn bytes? [x] (= (type x) byte-array-type))
accessoires à toutes les autres réponses. Ici, c'est comme une doublure: pour d'autres primitives, reportez-vous à http://docs.oracle.com/javase/7/docs/api/java/lang/class.html#getName%28%29 (ou la spécification Java). Ou faites simplement ce que Gerrit suggère avec car les performances ont été mentionnées, voici un petit résultat de référence d'exécution mais l'une de ces approches ne sera probablement pas un goulot d'étranglement dans la performance. < / p> p> (type (xyz-array 0)) code>. Spécifiquement, vous pouvez utiliser: p>
(heure (DoSimes [_ 500000] (byte-tableau? X) )) code>, et avec
octe-array-class code> def'd p>
instance? code> vs code> vs < Code> Type code> instance? gagne p>
partielle code> vs
defn code> = defn gagne p>
Je ne sais pas ce que le code de la clojure serait, mais vous pouvez créer un tableau vide pour chaque type primitif, appelez getclass () sur ceux-ci et mettre en cache les résultats. L'objet de classe doit être identique pour chaque éventail de ce type primitif - vous comparez les cachees avec
objet.getclass () code>. (getclass () ne devrait pas vraiment être un appel lent)