简体   繁体   English

Clojure:如何执行一系列函数?

[英]Clojure: How to execute a sequence of functions?

I have a sequence of functions (which mutate some objects) I'd like to execute, which works if I do this: 我有一系列函数(改变一些对象)我想执行,如果我这样做,它可以工作:

(foo1)
(foo2)
(foo3)

However, I want to put this code in a function so I can execute this sequence whenever I want. 但是,我想把这段代码放在一个函数中,这样我就可以随时执行这个序列。 If I do this: 如果我这样做:

(defn run-foos [] (do (foo1) (foo2) (foo3)))

The mutations created by run-foos is not the same as the 3 separate statements earlier. run-foos创建的突变与之前的3个单独语句不同。 I apologize that I can't concisely summarize the behavior of my program here, but basically I see there is some behavioral differences between the first and second versions of the code above. 我很抱歉,我不能在这里简明地总结我的程序的行为,但基本上我看到上面代码的第一个和第二个版本之间存在一些行为差异。

What I want to do is have a function run-foos that will execute foo1 , foo2 , and foo3 that runs exactly like I called each one individually in a row. 我想要做的是有一个函数run-foos ,它将执行foo1foo2foo3 ,其运行方式与我连续单独调用每个函数一样。 How can I do this? 我怎样才能做到这一点?

Without seeing the rest of your code, the difference here is not obvious (in general the two are the same). 没有看到你的其余代码,这里的差异并不明显(一般来说两者是相同的)。

The only reason there should be any difference between the two pieces of code you have is if the first one was entered at the repl and foo1 or foo2 returned a lazy result of some sort. 你拥有的两段代码之间应该有任何区别的唯一原因是,如果在repl中输入第一个代码,并且foo1foo2返回了某种类型的惰性结果。 In that case the repl will have forced the lazy result while printing it, and run-foos would not have. 在这种情况下,repl会在打印时强制执行惰性结果,而run-foos不会。

If that is your problem, then it would be better to keep using run-foos but refactor your other functions so that they don't mix side-effects and laziness. 如果那是你的问题,那么最好继续使用run-foos但重构你的其他功能,这样它们就不会混合副作用和懒惰。

This variant will work only with mutable data. 此变体仅适用于可变数据。

(defn run-foos [] (do (foo1) (foo2) (foo3)))

But standard clojure data structures are immutable. 但标准的clojure数据结构是不可变的。 So, every time when your data pass throught function independetly, functions will be work with default data, which with no mutate by function. 因此,每当您的数据独立地通过函数时,函数将使用默认数据,其中没有函数的变异。 Furthermore, run-foos will return data from only last expresion, ie (foo3). 此外, run-foos将仅从最后一次表达返回数据,即(foo3)。

«The values of all but the last expression are discarded, although their side effects do occur.» (Emerick, Carper, Grand: Clojure programming, 2012) «除了最后一个表达式之外的所有值都会被丢弃,尽管它们的副作用确实会发生。»(Emerick,Carper,Grand:Clojure programming,2012)

I think that you need thread-macro: 我认为你需要线程宏:

(-> data
    foo1
    foo2
    foo3)

It expands to (foo3 (foo2 (foo1 data))) at compile-time. 它在编译时扩展为(foo3 (foo2 (foo1 data))) Data will passed to functions along the chain and you will get what you want. 数据将传递给链中的功能,您将得到您想要的。

To read about -> macro with examples here: https://clojuredocs.org/clojure.core/-%3E 在这里阅读->宏示例: https//clojuredocs.org/clojure.core/-%3E

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM