Clojure:让作用域和函数返回值

Posted

技术标签:

【中文标题】Clojure:让作用域和函数返回值【英文标题】:Clojure: let scope and function return value 【发布时间】:2012-01-01 09:36:10 【问题描述】:

我在弄清楚如何使用“let”表单时遇到了一些麻烦。在下面的示例中,我想在本地绑定值“cols”,以便稍后在函数中对其进行处理。然而,我注意到的是,如果我使用“let”,函数 sel-opt-tmp 将返回一个 nil 值而不是一个列表。

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

(prn (sel-opt-tmp))

*上面的代码返回一个nil值。

我知道“let”只绑定函数范围内的值,我不知道是否有办法将值传递到 let 范围之外。也许有我不知道的“返回”之类的东西?或者这只是糟糕的设计,在这种情况下我根本不应该使用绑定(这往往会创建难以阅读的长链函数)?

【问题讨论】:

let 表单隐式返回它包含的最后一个表达式,在您的情况下是不可见的nil。您需要在 let 表单的正文中使用 cols 才能将其返回。 "let" only binds a value in the scope of a function -- 这并不完全正确。 lets 几乎可以出现在任何地方,绑定名称的范围是let 表达式。 【参考方案1】:

它返回 nil 因为 let 语句的内容为空(或 nil)。试试:

(let [cols "test"] cols)

这将返回cols 的值。正如 seh 所说,let 语句的计算结果为其最后一个子表达式的值。

【讨论】:

let 表单本身就是一个表达式,它计算为其最后一个子表达式的值!【参考方案2】:

正如您提到的,在范围之外传递值没有这样的问题。 绑定 cols 仅在范围内有效,但(:ks cols) 的生命周期不受类似限制。 (这就是你有垃圾收集的原因:你可以返回指向数据的值,只要有对它的引用,数据就会一直存在。)

如果您从函数中得到 nil,这可能意味着 cols 没有 :ks 键...或者确实可能不是地图。由于colsfilter 的结果,所以它是一个序列,当:ks 关键字用作函数时,它对于非集合返回nil。为防止此类错误,始终编写 (cols :ks) 而不是 (:ks cols) 可能是一个有用的约定,这样当您认为地图是其他东西时就会出错。

【讨论】:

您好,我做了一个小测试,结果仍然为零。代码在上面。

以上是关于Clojure:让作用域和函数返回值的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript的进阶之路函数简介,变量作用域和内存问题

作用域和闭包

作用域和闭包

clojure 函数,左值和返回值

作用域和闭包闭包

函数的返回值作用域变量的读写规则