[英]How to implement a For loop in Clojure
我想在 Clojure 中實現這個小代碼,但我很掙扎:
struct mystruct {
int id;
int price;
};
mystruct mydata[10];
for (int i=0; i<10; i++) {
myfunction(mydata[i].id, mydata[i].price);
//other things...
}
我是 Clojure 的初學者,做這樣簡單的事情對我來說真的很復雜,但我真的想盡可能多地學習,因為我知道 Clojure 有很大的優勢,比如使用引用......
如果有人可以幫助我,我將不勝感激。 謝謝!!
將命令式 for 循環轉換為 Clojure 的一種方法是使用for
宏。
(for [i (range 10)] (inc i))
上面的函數將返回從 0 到 9 以 1 遞增的所有數字。但是,看起來您只是想遍歷一個連續的集合並使用每個項目。 如果這就是您所需要的,那么您不需要引用索引值,而是可以直接引用每個項目。
(for [d my-vec-of-data] (my-function d))
但是,對於這種簡單的情況, map
函數可能是更好的選擇,因為它旨在調用帶有集合參數的函數。 下面的例子相當於上面的for
的使用。
(map my-function my-vec-of-data)
map
和for
都返回由my-function
返回的值組成的值my-function
。 這是因為 Clojure 的數據結構是不可變的,所以需要返回一個新的集合。 如果這不是您所需要的,或者您的函數有副作用,您可以使用doseq
而不是for
,后者返回nil
。
Jeremy 的回答非常適合如何在慣用的 Clojure 中執行 for 循環。
如果您真的想要 Clojure 中的命令式 for 循環,您可以使用以下宏創建一個:
(defmacro for-loop [[sym init check change :as params] & steps]
`(loop [~sym ~init value# nil]
(if ~check
(let [new-value# (do ~@steps)]
(recur ~change new-value#))
value#)))
用法如下:
(for-loop [i 0 (< i 10) (inc i)]
(println i))
doseq
做一些類似於for-loop
用法的事情:
(doseq [i (for [i (range 10)] (inc i))]
(println "i=" i))
綁定類似於 Clojure 中的for
。 但是,它不會通過計算doseq
的表達式來返回列表。 它為序列中的每個值執行表達式並返回nil
。
要遍歷 seq,您可以簡單地使用:
(doseq [value list]
(println "Your expression here" value)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.