Clojure: разрешить объем и функцию возвращаемого значения

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

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

(prn (sel-opt-tmp))

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

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

Ответ 1

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

(let [cols "test"] cols)

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

Ответ 2

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

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