2010-02-05 7 views
22

Es scheint, als ob ich Probleme beim Zugriff auf Integer.parseInt in comp haben. Ich kann es in der Regel wie folgt zugreifen:Wie übergebe ich eine statische Methode an comp in clojure?

user=> (Integer/parseInt "123") 
123 

Aber wenn ich es in comp, erhalte ich eine Fehlermeldung:

user=> (def vect-to-int (comp Integer/parseInt (partial apply str))) 
java.lang.Exception: Unable to find static field: parseInt in class java.lang.Integer (NO_SOURCE_FILE:3) 

Es klingt für mich wie es versucht, ein Feld auf Integer zu finden, wenn es sollte nach einer Methode suchen. Wie kann ich Integer.parseInt so verwenden? Und gibt es eine bessere Möglichkeit, einen Vektor von Zeichen in eine int zu konvertieren?

Antwort

26

Clojure-Funktionen sind Java-Methoden, aber Java-Methoden sind keine Clojure-Funktionen Zum Beispiel Clojure-Funktionen haben Metadaten und so. Wenn Sie eine Java-Methode verwenden möchten, für die eine Clojure-Funktion aufgerufen wird, haben Sie zwei Möglichkeiten, es aufzuwickeln, memfn und fun or #() memfn ist eine veraltete Funktion, die eine Java-Methode in einer Clojure-Funktion (es ist gut zu wissen, dass es existiert) auch wenn es nicht oft benutzt wird). Die allgemein akzeptierte Art und Weise Java-Methoden zu einpacken ist:

#(. instance method arg1 argN) 

oder für statische Methoden

#(Class/MethodName arg1 argN) 
+0

Ich denke, die erste Zeile nicht ganz richtig ist, wenn es wirklich den Punkt über :) bekommt –

7
(def vec-to-int (comp #(Integer/parseInt %) (partial apply str))) 

Oder

(def vec-to-int #(Integer/parseInt (apply str %))) 

partial und comp sind in der Regel nicht so prägnant in Clojure als #() mit Hilfe eines anonymen fn zu machen. Persönlich würde ich es auf diese Weise schreiben:

(defn vec-to-int [x] (Integer/parseInt (apply str x))) 

Sie können dies mit einfachen def, aber was gewinnen Sie def statt defn verwenden, wirklich? Die Verwendung von def verdeckt die Tatsache, dass Sie eine Funktion definieren. defn richtet auch zusätzliche Metadaten für Sie ein (Arglists), die def nicht tut.

Auf jeden Fall ist dies eine allgemeinere Art und Weise zu tun, was Sie tun:

(def vec-to-int #(bigint (apply str %))) 

Und noch allgemeiner:

(def vec-to-int #(read-string (apply str %))) 

davon ab, ob Sie zu handhaben zu können wollen andere Dinge als Ganzzahlen.

Verwandte Themen