`Iterator::inspect` 中闭包的副作用是否定义明确,因此它可以用于例如数数?

Are side-effects of the closure in `Iterator::inspect` well defined so it can be used for e.g. counting?

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

let it = ...;
let sum = it.sum::<u64>();

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

我想(滥用)使用 Iterator::inspect:

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

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

我会说它是有保证的,但你永远不会发现它明确地如此说明。正如你提到的,the documentation states:

Do something with each element of an iterator, passing the value on.

由于函数保证 运行 每个元素的闭包,并且语言保证闭包 运行 时发生的事情(根据闭包的定义),行为是安全的上。

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