为什么我的代码打印不出来? [英] Why isn't my code printing like it should?

查看:26
本文介绍了为什么我的代码打印不出来?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Clojure 中创建一个 for.

我正在关注 来自 Clojure 的备忘单网站.

例如:

(取 100 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y]))

我正在尝试创建自己的 for,它应该打印 100 次Hello World".

(取 100 (for [a (range 100):while (< a 100)](println "Hello World")))

出于某种原因,它没有打印 Hello World 100 次.为什么不呢?

解决方案

您需要注意的最重要的事情是 Clojure 中的序列是惰性的.这意味着序列中的项目仅在需要时才进行评估.这允许您处理无限序列.

大多数时候这就是您想要的,但是当您对序列项的值不感兴趣,而对创建序列项的函数的副作用感兴趣时,这可能会令人困惑.在您的示例中,该序列由 println 函数的 100 个返回值组成,即 100 次 nil - 不是很有趣.但是 println 函数具有将Hello World"打印到 stdout 的副作用.

问题是,如果您从未对序列中的项目执行任何操作,则永远不会评估 println 函数并且不会打印字符串.它有点适用于 REPL,因为 REPL 中的 P 代表打印 - 您输入的表达式的返回值被打印出来.要打印整个序列,必须对其进行评估,因此您会看到一堆Hello World",还有一堆 nils.如果您在 REPL 之外运行代码(不使用返回值),您将看不到 Hello World.

如果您对项目生成函数的副作用感兴趣,可以使用 doalldoseq.doall 强制计算整个序列并返回它:

(doall (for [a (range 100)] (println "Hello World")))

doseq 不返回序列(它返回 nil)并且具有类似 for 的语法:

(doseq [a (range 100)] (println "Hello World"))

另请注意,您实际上只需要提供一次所需的计数 (100).range 函数已经生成了一个包含 100 个项目的序列.代码中的 :while 子句是多余的,take 函数也是如此(从具有 100 个项目的序列中取出前 100 个项目并没有多大作用).

希望这有帮助!

I'm trying to create a for in Clojure.

I'm following the cheats sheet from the Clojure site.

e.g:

(take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y]))

I'm trying to create my own for which should print "Hello World" 100 times.

(take 100 (for [a (range 100) 
      :while (< a 100)] 
    (println "Hello World")
    )
)

For some reason it's not printing Hello World 100 times. Why not?

解决方案

The most important thing you need to be aware of, is that sequences in Clojure are lazy. That means the items in the sequence are only evaluated when they are needed. This allows you to work with infinite sequences.

Most of the time this is what you want, but it can be confusing when you are not really interested in the values of the sequence items, but in the side-effects of the functions that create the sequence items. In your example, the sequence is made up of 100 return values of the println function, that is 100 times nil - not very interesting. But the println function has the side-effect of printing "Hello World" to stdout.

The problem is, if you never do anything with the items in the sequence, the println functions are never evaluated and the strings are not printed. It kinda works in the REPL, because the P in REPL stands for print - the return value of the expression you typed in is printed. To print the whole sequence, it must be evaluated, so you see a bunch of "Hello World"s, but also a bunch of nils. If you run the code outside of the REPL (without using the returned value), you won't see the Hello Worlds.

If you're interested in the side-effects of your item-generating functions, you can use doall or doseq. doall forces the whole sequence to be evaluated and returns it:

(doall (for [a (range 100)] (println "Hello World")))

doseq doesn't return the sequence (it returns nil) and has a syntax like for:

(doseq [a (range 100)] (println "Hello World"))

Also note that you really only need to supply the desired count (100) once. The range function already produces a sequence with 100 items in it. The :while clause in your code is redundant, as is the take function (taking the first 100 items from a sequence with 100 items doesn't do much).

Hope this helps!

这篇关于为什么我的代码打印不出来?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆