![](/img/trans.png)
[英]Are Clojure transducers the same concept as intermediate operations on streams in Java?
[英]Converting the Java concept into Clojure
我對Clojure很新。 我有一個Java方法,包括一個布爾變量,我想重寫這個方法,以便在Clojure中使用相同的功能。 但我無法在Clojure中找到如何在運行時設置布爾值true和false。
下面的代碼片段基本上只強調布爾部分。我很難想到以函數的方式編寫它。
int calculate(...){
int y = 0;
boolean flag = false;
foreach(...){
if(!flag){
y = 1;
flag = true;
}
else{
y = -1;
flag = false;
}
}
return y;
}
這是我在Clojure的第一次嘗試:
(defn calculate [...]
( ??flag?? -> I do not know which macro I should use over here
(doseq [x ...]
(if (false? flag) (do 1 (set the flag true))
(do -1 (set the flag false)))))
如何在Clojure中實現相同的概念?
對於您擁有的Java代碼,將其轉換為Clojure的最簡單方法是跳過所有迭代並返回最終值:
(defn calculate [coll]
(odd? (count coll)))
如果你想要更精細的東西,我想你可以做點什么
(defn calc [coll flag]
(if (empty? coll)
flag
(recur (rest coll) (not flag))))
並稱之為
(defn calculate [coll]
(calc coll false))
這種遞歸並不是最慣用的風格,對於這個問題它有點瘋狂,但它演示了如何改變變量而不是變量,而是編寫一個表達式,當求值時產生傳遞給下一次迭代的值(參見recur call in上面的例子)。
重寫這樣的風格會更好
(defn calculate
([coll flag]
(if (empty? coll)
flag
(recur (rest coll) (not flag))))
([coll]
(calculate coll false)))
所以只有一個功能名稱要處理。 (我離開了另一個方向,認為對於Clojure的新人來說可能會更清楚。)
我的第二條評論建議你看看4clojure 。 這是一種很好的練習方式,一旦你有了解決方案,你就可以從其他用戶那里學到東西。
使用loop
/ recur
在Clojure中模擬迭代語句:
(defn calculate [...]
(loop [...
y 0
flag false]
...
(if (false? flag)
(recur ... 1 true) ;; "loop with x = ..., y = 1 and flag = true"
(recur ... -1 false)) ;; "loop with x = ..., y = -1 and flag = false"
... )
編輯:讓我詳細說明。 我從您的問題中理解的是,您無法將基於可變性(Java)的代碼轉換為Clojure。 這很自然。 Clojure在不變性方面很重要。
在Clojure程序中實現可變性的一種方法是使用引用類型,特別是原子 。 您的代碼可以在Clojure中以這種方式編寫:
(defn calculate [...]
(let [y (atom 0)
flag (atom false)]
(doseq [x ...]
(if (false? @flag)
(do (reset! y 1)
(reset! flag true))
(do (reset! y -1)
(reset! flag false))))
(... return some function of y and flag ...)))
有用。 但是,在Clojure中,大量使用原子和副作用並不是慣用的; 雖然有用,但是,與功能性,慣用的Clojure相比,並不是必需和繁瑣的。
在迭代的上下文中建模可變性的更好方法是在遞歸方面對其進行轉換,就像我在上面使用loop
/ recur
所做的那樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.