Pregunta

Quiero crear una instancia local de una clase de Scanner de Java en un programa de clojure. ¿Por qué esto no funciona?

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

pero me permitirá crear una instancia global como esta:

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

Tenía la impresión de que la única diferencia era el alcance, pero aparentemente no. ¿Cuál es la diferencia entre let y def ?

¿Fue útil?

Solución

El problema es que el uso de let es incorrecto.

Vamos a trabajar así:

(let [identifier (expr)])

Entonces tu ejemplo debería ser algo como esto:

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

Solo puede usar los enlaces léxicos hechos con let dentro del alcance de let (los parens de apertura y cierre). Vamos a crear un conjunto de enlaces léxicos. Utilizo def para hacer un enlace global y permite enlazar algo que quiero solo en el ámbito del let, ya que mantiene todo limpio. Ambos tienen sus usos.

NOTA: (Clase.) es igual que (Clase nueva), solo es azúcar sintáctica.

Otros consejos

LET no es un enlace léxico en el ámbito actual, sino que crea un nuevo ámbito léxico con los siguientes enlaces.

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

Sintaxis correcta:

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

Simplificado: def es para constantes globales, deja es para variables locales.

La sintaxis para ellos es diferente, incluso si los significados están relacionados.

permite tomar una lista de enlaces (pares de valores de nombre) seguidos de expresiones para evaluar en el contexto de esos enlaces.

def solo toma un enlace, no una lista, y lo agrega al contexto global.

Podría pensar en let como azúcar sintáctica para crear un nuevo ámbito léxico con fn y aplicarlo inmediatamente:

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

Para que pueda implementar let con una macro simple y fn :

(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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top