Frage

Ich mag eine lokale Instanz einer Java Scanner Klasse in einem clojure Programm machen. Warum funktioniert das nicht:

; gives me:  count not supported on this type: Symbol 
(let s (new Scanner "a b c"))

, aber es lässt mich eine globale Instanz wie folgt erstellen:

(def s (new Scanner "a b c"))

Ich hatte den Eindruck, dass der einzige Unterschied war, Umfang, aber anscheinend nicht. Was ist der Unterschied zwischen let und def?

War es hilfreich?

Lösung

Das Problem ist, dass die Nutzung von let falsch ist.

Lassen Sie funktioniert wie folgt:

(let [identifier (expr)])

So Ihr Beispiel so etwas wie dies sein sollte:

(let [s (Scanner. "a b c")]
  (exprs))

Sie können nur die lexikalischen Bindungen im Rahmen von let let gemacht verwenden (das Öffnen und Schließen Pars). Lassen Sie schafft nur eine Reihe von lexikalischen Bindungen. Ich benutze def eine globale Bindung für die Herstellung und lasse für die Bindung etwas, das ich nur im Rahmen der Let will, wie es Dinge sauber hält. Sie haben beide ihre Verwendung.

. HINWEIS: (. Klasse) ist das gleiche wie (neue Klasse), es ist nur syntaktischer Zucker

Andere Tipps

LET ist nicht „im aktuellen Bereich eine lexikalische Bindung machen“, sondern „einen neuen lexikalischen Gültigkeitsbereich mit den folgenden Bindungen machen“.

(let [s (foo whatever)]
  ;; s is bound here
  )
;; but not here
(def s (foo whatever))
;; s is bound here

Die korrekte Syntax:

(let [s (Scanner. "a b c")] ...)

Vereinfacht:. def für globale Konstanten ist, lassen ist für lokale Variablen

Die Syntax für sie ist anders, auch wenn die Bedeutung beziehen.

let nimmt eine Liste der Bindungen (Name Wertepaare), gefolgt von Ausdrücken im Rahmen derer zu bewerten verbindlich.

def dauert nur eine Bindung, keine Liste, und fügt sie den globalen Kontext.

denken Sie an let als syntaktischen Zucker

Sie könnten einen neuen lexikalischen Gültigkeitsbereich mit fn dann für die Erstellung der Anwendung sofort:

(let [a 3 b 7] (* a b))  ; 21
; vs.
((fn [a b] (* a b)) 3 7) ; 21

So Sie let mit einem einfachen Makro und fn implementieren könnte:

(defmacro fnlet [bindings & body]
  ((fn [pairs]
    `((fn [~@(map first pairs)] ~@body) ~@(map last pairs)))
   (partition 2 bindings)))

(fnlet [a 3 b 7] (* a b)) ; 21
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top