打印在clojure! (以懒惰的顺序)

时间:2011-10-14 11:17:08

标签: clojure

1)(def x (for [i (range 1 3)] (do (println i) i)))

2)(def x (for [i (range 1 3)] (do i)))

两者都产生相同的输出,那么println的用途是什么?

2 个答案:

答案 0 :(得分:10)

值计算自己,do块返回最后一个表达式的结果。这就是为什么(do 2)返回2,在下面的例子中。因为它返回2,当从REPL中评估时,2将作为结果打印到屏幕上。 但函数println会产生副作用,但返回nil。下面的副作用是将值2打印到标准输出。也打印nil,因为这是函数println的返回值。

user=> (do 2)
2
user=> (println 2)
2
nil

在您的示例中,输出相同,因为我在上面解释过。请注意自己的差异:

user=> (def x (for [i (range 1 3)] (do (println i) i)))
#'user/x
user=> x
(1
2
1 2)
user=> (def x (for [i (range 1 3)] (do i)))
#'user/x
user=> x
(1 2)

另请注意 for lazy

(def x (for [i (range 1 3)] (do (println i) i)))
#'user/x
user=> x
(1
2
1 2)
user=> x
(1 2)

第二次请求x时,仅打印(1 2)。为什么?因为懒惰。它仅在第一次请求时生成其元素(第一次请求x)。下一次,元素已经产生,因此do内的副作用不会再发生。

答案 1 :(得分:7)

在REPL中,它们可能产生(大致)相同的输出,但如果从已编译的程序运行则不会。 REP中的P代表Print - 它打印当前表达式的值。

尝试编译成Jar并运行它以查看差异。也永远不要忘记使用println意味着你的功能有副作用;您可能会发现需要强制评估函数(例如在do中)以产生输出。