For loop clojure中的For循环
IllegalArgumentException不知道如何从以下位置创建ISeq:java.lang.Long clojure.lang.RT.seqFrom 编辑:: 以下作品For loop clojure中的For循环,for-loop,clojure,For Loop,Clojure,IllegalArgumentException不知道如何从以下位置创建ISeq:java.lang.Long clojure.lang.RT.seqFrom 编辑:: 以下作品 (defn foo [arg] ( for [ i (range (count vector)) ] ( for [j arg ] [i j] ) ) ) 现在有人能帮我理解为什么它一开始不起作用吗?如果使用:whi
(defn foo [arg]
(
for [ i (range (count vector)) ]
(
for [j arg ]
[i j]
)
) )
现在有人能帮我理解为什么它一开始不起作用吗?如果使用
:while
,for loop
将返回null,因为第一个值为false,:when
更好
(defn foo [arg]
(def w arg)
(for [ i (range (count vector)) ]
(
for [j (range v) ]
[i j]
)
) )
user=>(对于[i(范围3)j(范围5)][i j])
([0 0] [0 1] [0 2] [0 3] [0 4] [1 0] [1 1] [1 2] [1 3] [1 4] [2 0] [2 1] [2 2] [2 3] [2 4])
user=>(对于[i(范围3)j(范围5):while((对于[i(范围3)j(范围5):当(
不知道如何创建ISeq from:java.lang.Long clojure.lang.RT.seqFrom
此错误消息准确地说明了异常的原因。
我猜您传递了一个long
值,其中需要seq
。
我可以复制它:
user=> (for [i (range 3) j (range 5)] [i j])
([0 0] [0 1] [0 2] [0 3] [0 4] [1 0] [1 1] [1 2] [1 3] [1 4] [2 0] [2 1] [2 2] [2 3] [2 4])
user=> (for [i (range 3) j (range 5) :while (< i j)] [i j])
()
user=> (for [i (range 3) j (range 5) :when (< i j)] [i j])
([0 1] [0 2] [0 3] [0 4] [1 2] [1 3] [1 4] [2 3] [2 4])
您的foo
功能正常。但是,arg
参数必须是seq
,
因为
arg
绑定在嵌套的for
到j
中,所以首先要知道的是,clojure的for
不是for循环,而是for循环
这意味着,它用于构建具有指定属性的列表(实际上是惰性序列)
您的原始版本如下所示:
user> (def v [1 2 3])
#'user/v
user> (defn foo [arg]
(for [ i (range (count v)) ]
(for [j arg ]
[i j])))
#'user/foo
user> (foo (range 3))
(([0 0] [0 1] [0 2]) ([1 0] [1 1] [1 2]) ([2 0] [2 1] [2 2]))
user> (foo 3)
; Evaluation aborted.
; Don't know how to create ISeq from: java.lang.Long
; [Thrown class java.lang.IllegalArgumentException]
(适用于[i(范围n))
j(范围w)
:let[n(*i j)]
:while(
(我没有发现您原始示例中的类强制转换异常)
它说的是:当i
做某事时,取i
和j
对。第一对i
和j
是i=0
和j=0
。0是否小于0?不,停下来。也就是说,您正在构造一个空序列
现在,如果我们将:while
更改为:when
,它的含义将更改为:对于i
和j
的每一对i
,并对它们进行处理。也就是说,当遇到i>=j时,不会停止构建序列,只需跳过这一对
接下来要注意的是println
。此函数打印其参数,但始终返回nil
。这个返回值是您在结果序列中得到的,打印被称为副作用。一般来说,您不希望惰性序列产生副作用,因为它们(副作用)会在需要时发生。也就是说,如果将返回的序列分配给某个变量,则不会调用println
s。当序列实现时,它们将开始弹出
底线是,不要把
for
看作一个循环,把它看作一个序列构造函数。在clojure中:while和:when的区别是什么:这很有趣。。。那么,我们如何实现功能意义上的序列呢?那么,如果我返回而不是打印,这是否意味着它将实现?您可以通过请求其元素来“实现”序列。它会被实现到需要的程度。例如,(取10(范围))
将只返回由范围
生成的无限序列的前10个整数。(实际上,take
也是惰性的,但是REPL不是,因此它强制实现。)您也可以使用doall
或dorun
显式强制实现(它们返回的内容不同)。同样相关的还有doseq
。此外,“传统”循环是通过loop
和recur
完成的,但这些通常被认为是创建更高级别抽象的低级构建块,如map
,过滤器
,for
,等等。对于[j(范围arg)],应该解决这个问题。
user> (def v [1 2 3])
#'user/v
user> (defn foo [arg]
(for [ i (range (count v)) ]
(for [j arg ]
[i j])))
#'user/foo
user> (foo (range 3))
(([0 0] [0 1] [0 2]) ([1 0] [1 1] [1 2]) ([2 0] [2 1] [2 2]))
user> (foo 3)
; Evaluation aborted.
; Don't know how to create ISeq from: java.lang.Long
; [Thrown class java.lang.IllegalArgumentException]
(for [i (range n)
j (range w)
:let [n (* i j)]
:while ( < i j)]
(println n))