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

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

问题描述

我正在尝试在Clojure中创建for。

I'm trying to create a for in Clojure.

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

例如:

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

我正在尝试为 $ c>应该会打印 Hello World 100次。

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")
    )
)

由于某种原因,它无法打印Hello World 100次。为什么不呢?

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

推荐答案

您需要了解的最重要的一点是Clojure中的序列是惰性的。这意味着仅在需要时才评估序列中的项目。

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.

在大多数情况下,这就是您想要的,但是当您对的值不真正感兴趣时,可能会造成混淆。序列项,但是在创建序列项的函数的副作用中。在您的示例中,该序列由 println 函数的100个返回值组成,即 nil 的100倍-不太有趣。但是 println 函数具有将 Hello World打印到标准输出的副作用。

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.

问题是,如果您从不对序列中的项目进行任何操作,则不会对 println 函数进行求值,也不会打印字符串。它在REPL中很有效,因为REPL中的P代表print-打印您键入的表达式的返回值。要打印整个序列,必须对其进行评估,以便您看到一堆 Hello World,以及一堆 nils 。如果您在REPL之外运行代码(不使用返回值),则不会看到Hello Worlds。

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.

如果您对以下方面感兴趣,项目生成功能的效果,您可以使用 doall doseq doall 强制对整个序列求值并返回:

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 不返回序列(返回 nil ),语法类似于 for

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

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

还请注意,您实际上只需要提供所需的计数(100)一次。 range 函数已经产生了一个包含100个项目的序列。代码中的:while 子句是多余的, take 函数也是如此(从序列中获取前100个项目)包含100个项目的功能并不多)。

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).

希望这会有所帮助!

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

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