Clojure: пусть область и функция возвращают значение - PullRequest
14 голосов
/ 18 ноября 2011

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

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

(prn (sel-opt-tmp))

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

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

Ответы [ 2 ]

21 голосов
/ 18 ноября 2011

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

(let [cols "test"] cols)

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

3 голосов
/ 18 ноября 2011

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

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

...