2011-11-18 12 views
12

Tengo algunos problemas para averiguar cómo usar el formulario "let". En el ejemplo siguiente, me gustaría vincular localmente el valor "cols" para trabajar más adelante en la función. Lo que estoy notando, sin embargo, es que si uso "let" la función sel-opt-tmp devolverá un valor nil en lugar de una lista.Clojure: deje que el alcance y la función devuelvan el valor

(defn sel-opt-tmp [] 
    (let [cols "test"])) 

(prn (sel-opt-tmp)) 

* El código anterior devuelve un valor nulo.

Entiendo que "let" solo vincula un valor en el alcance de una función, lo que no sé es si hay una manera de pasar el valor fuera del alcance de let. Tal vez hay algo así como "retorno" que no tengo conocimiento? ¿O es simplemente un mal diseño y no debería usar el enlace en este caso (esto tiende a crear largas cadenas de funciones que son difíciles de leer, sin embargo)?

+2

El formulario 'let' devuelve implícitamente la última expresión que contiene, que en su caso es el' nil' invisible. Necesitas usar 'cols' en el cuerpo de la forma' let' para que se devuelva. – seh

+0

'" let "solo enlaza un valor en el alcance de una función' - eso no es del todo cierto. 'let's puede aparecer más en cualquier lugar, y el alcance de los nombres enlazados es la expresión' let'. –

Respuesta

17

Devuelve nil porque el contenido de la instrucción let está vacío (o nulo). Proveedores:

(let [cols "test"] cols)

que devolverá el valor de cols. Como dice seh, una instrucción let evalúa el valor de su última sub-expresión.

+1

Una forma 'let' es en sí misma una expresión, que * evalúa * con el valor de su última sub-expresión. –

+0

Gracias Matt, he actualizado la redacción. No sé por qué no lo hice antes ... –

3

No hay tal problema con pasar valores fuera del alcance como usted menciona. La vinculación cols está en vigor solo dentro del alcance, pero la duración del valor de (:ks cols) no está restringida de forma similar. (Es por eso que tiene recolección de basura: puede devolver valores que apuntan a datos, y los datos permanecen activos mientras haya referencias)

Si obtiene nil de la función, eso significa que cols no tiene una clave :ks ... o puede que no sea un mapa. Como cols es el resultado de filter, es una secuencia, y cuando se usa la palabra clave :ks como función, devuelve nil para las no colecciones. Para protegerse contra ese tipo de errores, puede ser una convención útil escribir siempre (cols :ks) en lugar de (:ks cols) para que obtenga un error cuando lo que cree que es un mapa es otra cosa.

+0

Hola, hice una pequeña prueba y sigo teniendo problemas. El código está arriba. – kfk

Cuestiones relacionadas