n = (count somevector)
(foo [w] ( for [i (range n)
j (range w)
:let [n (* i j)]
:while ( < i j)
]
(println n)))
我跑的时候。
=&GT; (foo 10)
ClassCastException
clojure
。lang
。LazySeq
无法投放到clojure
。lang
。IFn
HelloWorld.core / foo
我真正想做的是有几个嵌套的for循环并且有一些ifs以及其他内部做一些检查。
编辑::
事实证明以下内容也会导致错误
(defn foo [arg]
(
for [ i (range (count vector)) ]
(
for [j arg ]
[i j]
)
) )
IllegalArgumentException不知道如何创建ISeq:java.lang.Long clojure.lang.RT.seqFrom
编辑::
以下作品
(defn foo [arg]
(def w arg)
(for [ i (range (count vector)) ]
(
for [j (range v) ]
[i j]
)
) )
现在有人可以帮助我理解为什么它首先不起作用?
答案 0 :(得分:5)
如果您使用:while
,for-loop
将返回null,因为第一个值为false,:when
更好。
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])
答案 1 :(得分:3)
不知道如何创建ISeq:java.lang.Long clojure.lang.RT.seqFrom
此错误消息准确说明了异常的原因。
我猜您通过long
值,预计会有seq
。
我可以重现它:
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]
您的foo
功能有效。但是,arg
参数必须是seq
,
因为arg
在嵌套for
到j
答案 2 :(得分:2)
你应该知道的第一件事是,clojure for
不是for循环,而是list comprehension。
这意味着,它用于使用指定的属性构建列表(实际上是惰性序列)。
您的原始for
如下所示:
(for [i (range n)
j (range w)
:let [n (* i j)]
:while ( < i j)]
(println n))
(我没有用原始示例获得类别转换异常)。
它的含义是:在i
执行某些操作时,需要成对j
和i < j
。第一对i
和j
是i = 0
和j = 0
。是0&lt; 0?不停。也就是说,你正在构建一个空序列。
现在,如果我们使用:while
更改:when
,则会将其含义更改为:对于每对i
和j
,{ {1}},并与他们做点什么。也就是说,当你遇到i&gt; = j时,你不会停止构建序列,你只需跳过这一对。
接下来要注意的是i < j
。此函数打印其参数,但始终返回println
。此返回值是您在结果序列中获得的值,打印称为副作用。一般来说,你不希望有懒惰序列的副作用,因为它们(副作用)会在需要时发生。也就是说,如果将返回的序列分配给某个变量,则不会调用nil
。当序列实现时,它们会弹出。
最重要的是,不要将println
视为循环,将其视为序列构造函数。