2010-07-18 2 views
10

Ich schreibe einen Clojure-Code, der von einer Anzahl von Konstanten abhängt.Was ist das Clojure-Äquivalent einer "öffentlichen statischen endgültigen" Konstante in Java

Sie werden innerhalb enger innerer Schleifen verwendet, daher ist es wichtig, dass sie von der Clojure Compiler + JVM Kombination so effizient wie möglich genutzt und optimiert werden. Ich würde normalerweise eine "public static final" -Konstante in Java für den gleichen Zweck verwenden.

Was ist der beste Weg, diese zu deklarieren?

Antwort

6

Ich denke, def-Dinge im globalen Namespace ist ungefähr so ​​nah wie Sie kommen können.

+2

Das Hinzufügen der: const-Metadaten führt dazu, dass es zur Kompilierungszeit inline wird, siehe Antwort von @amalloy. Die globalen Defs sind Vars, die während des Schließens optimiert und zur Laufzeit aufgelöst werden können. – deterb

2

Wie oben erwähnt def oder atom verwenden, denken Sie daran, Daten sind unveränderlich, wenn Sie also einige Konstanten in einer Liste deklarieren, ändern sie sich nicht.

+0

Wenn er etwas Veränderliches wollte, würde er nach einer Konstante fragen und sowieso würden Sie normalerweise eine Liste mit Atomen erstellen. Sie würden eine Atomliste oder eine Ref-Liste erstellen. – nickik

2

Es gibt keine defconst, also nur mit einem globalen Def ist idiomatic; Was die Optimierung angeht, wird das JIT die Dinge schnell machen.

3

Wenn wirklich, wirklich, wirklich wollen die Konstante an Ort und Stelle (ich glaube, die JIT wird feststellen, dass der Wert konstant ist und das Richtige tun, obwohl), können Sie ein Makro verwenden.

(defmacro my-constant [] 5)

Das ist ziemlich hässlich, aber leistungskritischer Code wird immer hässlich sein, denke ich.

(do-stuff (my-constant) in-place)

Achten Sie darauf, was Sie in das Makro, obwohl! Ich würde das nicht für mehr als einige wörtliche Konstanten halten. Insbesondere keine Objekte.

3

Wenn die Verwendung von def nicht schnell genug ist, können Sie versuchen, einen gebundenen Alias ​​mit der Nummer let zu erstellen, bevor Sie Ihre enge Schleife eingeben, um jedes Mal eine Var zu vermeiden.

+0

Danke - also bin ich richtig, wenn ich sage, dass, wenn Sie das nicht tun, es am Ende die Variable der Variablen bei jedem Zugriff auf die Konstante dereferenzieren wird? – mikera

6

Ich glaube, Clojure 1.3 (oder vielleicht 1.4) können Sie ein ^:constant Tag auf eine def setzen, bedeutet für den Compiler, dass dies eine Konstante sein sollte und alle Referenzen zur Kompilierzeit aufgelöst werden sollten.

bearbeiten

Offenbar ist es Clojure 1.3, und es ist ^:const, nicht ^:constant. Eine Zusammenfassung finden Sie unter How does Clojure ^:const work?.

Verwandte Themen