2011-11-18 16 views
12

我在计算如何使用“let”表单时遇到了一些麻烦。在下面的例子中,我想在本地绑定值“cols”,以便稍后在函数中使用它。然而,我注意到的是,如果我使用“let”,函数sel-opt-tmp将返回一个零值而不是列表。Clojure:让示波器和函数返回值

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

(prn (sel-opt-tmp)) 

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

我明白,“让”只绑定一个函数范围内的值,我不知道是否有一种方法可以将值传递给let范围。也许有一些我不知道的“回归”?或者这仅仅是糟糕的设计,在这种情况下我不应该使用绑定(这往往会产生很长的功能链,虽然很难阅读)。

+2

'let'形式隐式返回它包含的最后一个表达式,在你的情况下它是不可见的'nil'。您需要在'let'表单的主体中使用'cols'来让它返回。 – seh

+0

'“let”只绑定函数范围内的值 - 这不完全正确。 'let's可以出现在任何地方,绑定名称的范围是'let'表达式。 –

回答

17

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

(let [cols "test"] cols)

将返回的cols值。正如seh所说,let语句评估的是其最后一个子表达式的值。

+1

一个'let'形式本身就是一个表达式,它将*评估为其最后一个子表达式的值! –

+0

谢谢马特,我已经更新了措辞。不知道为什么我以前没有... –

3

您提到的范围之外的值不存在这样的问题。 绑定cols仅在该范围内有效,但的的生存期不受类似限制。 (这就是为什么你有垃圾收集:您可以返回指向数据值,只要有对它的引用数据停留住。)

如果从功能,则可能意味着cols确实得到零没有:ks键......或者实际上可能不是地图。由于colsfilter的结果,因此它是一个序列,并且当:ks关键字用作函数时,它将返回nil用于非集合。为了防范这种错误,总是编写(cols :ks)而不是(:ks cols)可能是一个有用的约定,以便在您认为地图是其他内容时出现错误。

+0

你好,我做了一个小测试,仍然是零。代码在上面。 – kfk