我有一系列函数(它们会改变某些对象)我想执行它,如果我这样做就可以了:
(foo1)
(foo2)
(foo3)
但是,我想把这段代码放在一个函数中,这样我就可以随时执行这个序列。如果我这样做:
(defn run-foos [] (do (foo1) (foo2) (foo3)))
run-foos
创建的突变与之前的3个单独的声明不同。我很抱歉我不能在这里简明地总结我的程序的行为,但基本上我看到上面代码的第一版和第二版之间存在一些行为差异。
我想要做的是有一个函数run-foos
,它将执行foo1
,foo2
和foo3
,其运行方式与我在一行中单独调用每个。我怎么能这样做?
答案 0 :(得分:3)
在没有看到其余代码的情况下,这里的差异并不明显(一般来说两者是相同的)。
在您拥有的两段代码之间存在任何差异的唯一原因是,如果第一个代码是在repl上输入的,foo1
或foo2
返回了某种懒惰的结果。在这种情况下,repl会在打印时强制执行惰性结果,而run-foos
则不会。
如果这是你的问题,那么继续使用run-foos
会更好,但重构你的其他功能,以免他们混淆副作用和懒惰。
答案 1 :(得分:0)
此变体仅适用于可变数据。
(defn run-foos [] (do (foo1) (foo2) (foo3)))
但标准的clojure数据结构是不可变的。因此,每当您的数据独立地通过函数时,函数将使用默认数据,其中没有函数的变异。此外,run-foos
将仅从最后一次表达返回数据,即(foo3)。
«除了最后一个表达式之外的所有值都会被丢弃,尽管它们会产生副作用。» (Emerick,Carper,Grand:Clojure编程,2012)
我认为你需要线程宏:
(-> data
foo1
foo2
foo3)
它在编译时扩展为(foo3 (foo2 (foo1 data)))
。数据将传递给链中的函数,您将获得所需的信息。
在此处阅读有关->
宏的示例:
https://clojuredocs.org/clojure.core/-%3E