Являются ли побочные эффекты закрытия в `Iterator :: inspect` хорошо определенными, чтобы его можно было использовать, например, для подсчет? - PullRequest
0 голосов
/ 13 января 2019

У меня есть итератор, и я хотел бы сложить его хорошим методом (скажем, Iterator::sum):

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

Тогда я замечаю, что мне также нужно знать количество элементов в итераторе. Я мог бы написать цикл for и выполнить подсчет и суммирование вручную, но это нехорошо, так как мне приходится менять потенциально длинную цепочку адаптеров итераторов и все такое. Кроме того, в моем реальном коде я использую не sum, а более сложный «метод складывания», логику которого я не хочу копировать.

У меня была идея (а) использовать Iterator::inspect:

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

Это работает , но работает ли оно случайно или такое поведение гарантировано? В документации inspect упоминается, что замыкание вызывается для каждого элемента, но также говорится, что в основном используется как инструмент отладки. Я не уверен, что использование этого способа в рабочем коде - хорошая идея.

1 Ответ

0 голосов
/ 13 января 2019

Я бы сказал, что это гарантировано, но вы никогда не найдете это в явном виде. Как вы упоминаете, документация гласит :

Сделайте что-нибудь с каждым элементом итератора, передав значение.

Поскольку функция гарантирует выполнение замыкания для каждого элемента, а язык гарантирует, что происходит при запуске замыкания (по определению замыкания), на поведение можно положиться.

При этом, если у вас есть один или несколько побочных эффектов, может быть лучше отказаться от тяжелой цепочки и перейти к скучному циклу for для удобства чтения, но это будет зависеть от точного случая.

...