![](/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.