`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
循环以提高可读性,但这取决于具体情况。
我有一个迭代器,我想用一个很好的方法折叠它(比如 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
循环以提高可读性,但这取决于具体情况。