`Iterator::inspect` 中闭包的副作用是否定义良好,以便可以用于计数等?

Luk*_*odt 6 iterator side-effects rust

我有一个迭代器,我想用一个很好的方法折叠它(比如说Iterator::sum):

let it = ...;
let sum = it.sum::<u64>();
Run Code Online (Sandbox Code Playgroud)

然后我注意到我还需要知道迭代器中元素的数量。我可以编写一个for循环并手动进行计数和求和,但这并不好,因为我必须更改可能很长的迭代器适配器链以及所有这些。此外,在我的真实代码中,我没有使用sum,而是使用更复杂的“折叠方法”,我不想复制该逻辑。

我有一个想法(ab)使用Iterator::inspect

let it = ...;
let mut count = 0;
let sum = it.inspect(|_| count += 1).sum::<u64>();
Run Code Online (Sandbox Code Playgroud)

这是可行的,但它是巧合还是这种行为有保证?的文档inspect提到每个元素都会调用闭包,但也指出它主要用作调试工具。我不确定在生产代码中以这种方式使用它是否是一个好主意。

She*_*ter 5

我想说这是有保证的,但你永远不会发现它如此明确地说明。正如您所提到的,文档指出

对迭代器的每个元素执行一些操作,传递值。

由于函数保证为每个元素运行闭包,并且语言保证运行闭包时会发生什么(根据闭包的定义),因此该行为是安全可靠的。

话虽这么说,一旦出现一个或多个副作用,最好避免重链并转向无聊的for循环以提高可读性,但这取决于具体情况。