在另一个问题中,一位用户建议编写如下代码:
def list = ['a', 'b', 'c', 'd']
def i = 0;
assert list.collect { [i++] } == [0, 1, 2, 3]
在其他语言中,这样的代码被认为是不好的做法,因为 collect 的内容会改变其上下文的状态(这里它会改变 的值i
)。换句话说,闭包有副作用。
这样的高阶函数应该能够并行运行闭包,并再次将其组装到一个新列表中。如果闭包中的处理是长时间的、CPU 密集型操作,则可能值得在单独的线程中执行它们。collect
更改为使用 anExecutorCompletionService
来实现这一点很容易,但它会破坏上面的代码。
另一个问题的例子是,如果出于某种原因,collect
以相反的顺序浏览集合,在这种情况下,结果将是[3, 2, 1, 0]
. 请注意,在这种情况下,列表没有被还原,0 实际上是对 'd' 应用闭包的结果!
有趣的是,这些函数记录在Collection 的 JavaDoc中的“迭代此集合”中,这表明迭代是顺序的。
groovy 规范是否明确定义了高阶函数(如collect
oreach
)中的执行顺序?上面的代码是坏了,还是没问题?