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

vik*_*hal 1 clojure

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

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

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

Mic*_*ent 10

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

user=> (do 2)
2
user=> (println 2)
2
nil
Run Code Online (Sandbox Code Playgroud)

在你的例子中,输出是一样的,因为我在上面解释了.请注意自己的差异:

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)
Run Code Online (Sandbox Code Playgroud)

另请注意,因为懒惰:

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

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


Adr*_*uat 7

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

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