Dieser Code ist nicht mein "echter" Code, sondern ist ein Beispiel für das Problem von einem viel größeren Algorithmus. Es hat eine Weile gedauert, bis ich (mit (set! *warn-on-reflection* true)
) diese Reflexion gefunden hatte.Clojure Fehlbetrag auf Typ Inferenz
Mit Typ Hinting kommt zu dynamischen Sprachen (z. B. Python und Clojure) und aggressive Typ-Referenzierung zu anderen (z. B. Scala), scheint es seltsam, dass ich explizit mit (int ...)
umgewandelt werden muss.
Warum weiß clojure nicht, dass (aget int-array int)
einen int zurückgibt?
Kann ich die if-Anweisung selbst annotieren, um zu sagen, dass sie ein int zurückgibt?
Wenn nicht, kann ich eine Inline-Funktion verwenden, um die Fehler zu vermeiden.
(let [a (int-array [4 5 6 7])]
;(aset a 1 (int (if (seq a) 40 (aget a 0))))) ;; fast
(aset a 1 (if (seq a) 40 (aget a 0)))) ;; slow
Ich weiß, dass Typ-Hinting ist nicht weniger als die Eingabe dieses int
Anruf aber das kann nicht der Fall in komplexeren Code sein.
Clojure [Literal Integralzahlen] (https://clojure.org/reference/reader#_literals) sind Java Long Objekte. Deshalb müssen Sie es explizit in einen int-nativen jvm-Wert in Ihrem Code zwingen, wenn Sie einen Reflektionsaufruf vermeiden möchten. – kawas44
@ kawas44 danke, dass die Perspektive auf den ersten Teil der akzeptierten Antwort hinzugefügt. –
Zuerst, werfen Sie einen Blick auf aset-int, was zu sein scheint, was Sie wollen. Möglicherweise nicht relevant, aber da ich gesehen habe, dass andere darüber stolpern, dachte ich, ich würde es nur erwähnen.In clojure tendieren Sie nur dazu, int-array, aget, aset usw. zu verwenden, wenn Sie ein Java-Interop ausführen müssen, bei dem Sie Java-Arrays übergeben/empfangen müssen. Wenn Sie nur auf der Clojure-Ebene arbeiten, müssen Sie nur Clojure-Vektoren verwenden. Erwähnen Sie es, weil ich Leute aus anderen Sprachen, vor allem Java, gesehen habe, die dachten, dass sie aget/aset verwenden müssen, nur um Algorithmen zu verwenden, die Arrays verwenden. Ein Clojure-Vektor ist ein Array. –