2011-11-18 1 views
12

У меня возникли проблемы, связанные с использованием формы «let». В приведенном ниже примере я хотел бы локально связать значение «cols», чтобы впоследствии работать над ним. Однако я замечаю, что если я использую «let», функция sel-opt-tmp вернет значение nil вместо списка.Clojure: допустимый объем и функция возвращаемого значения

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

(prn (sel-opt-tmp)) 

* Приведенный выше код возвращает значение nil.

Я понимаю, что «let» связывает только значение в области действия функции, чего я не знаю, если есть способ передать значение из области let. Может быть, есть что-то вроде «возвращения», о котором я не знаю? Или это просто плохой дизайн, и я не должен использовать привязку вообще в этом случае (это, как правило, создает длинные цепочки функций, которые трудно читать, хотя)?

+2

Форма 'let' неявно возвращает последнее содержащееся выражение, которое в вашем случае является невидимым' nil'. Вам нужно использовать 'cols' в теле' let', чтобы он был возвращен. – seh

+0

'' let "только привязывает значение в области функции' - это не совсем так. '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''' '' ''' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' –

ответ

17

Он возвращает nil, потому что содержимое оператора let пусто (или nil). Попробуйте:

(let [cols "test"] cols)

который будет возвращать значение cols. Как говорит seh, оператор let оценивает значение своего последнего подвыражения.

+1

Форма 'let' сама является выражением, которое * оценивает * на значение его последнего подвыражения! –

+0

Спасибо Мэтту, я обновил формулировку. Не знаю, почему я не раньше ... –

3

Нет такой проблемы с передачей значений за пределами области действия, о которой вы упоминаете. Перевязка cols действует только в пределах объема, но время жизни значения (:ks cols) не ограничено. (Вот почему у вас есть сбор мусора: вы можете возвращать значения, указывающие на данные, и данные остаются в живых до тех пор, пока есть ссылки на него.)

Если вы получаете нуль от функции, это, вероятно, означает, что cols делает не имеет ключа :ks ... или может быть не карта. Поскольку cols является результатом filter, это последовательность, и когда ключевое слово :ks используется как функция, оно возвращает nil для не-коллекций. Чтобы защититься от таких ошибок, может быть полезным соглашением всегда писать (cols :ks) вместо (:ks cols), чтобы вы получили сообщение об ошибке, когда то, что вы считаете картой, является чем-то другим.

+0

Привет, я сделал небольшой тест и все еще получаю ноль. Код выше. – kfk