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中的副作用不会再发生.
在REPL中,它们可以产生(大致)相同的输出,但如果从已编译的程序运行则不会.REP中的P代表Print - 它打印当前表达式的值.
尝试编译成Jar并运行它以查看差异.也永远不要忘记使用println意味着你的功能有副作用; 您可能会发现需要强制评估函数(例如在do中)以产生输出.