Box<[T]>
не реализует FromIterator<&T>
, поэтому я предполагаю, что ваш действительный внутренний итератор - это то, что приводит к владению T
s.
FromIterator<T>
для Box<[T]>
для пересылки в Vec<T>
, который использует size_hint()
, чтобы зарезервировать пространство для lower
+ 1 элементов, и перераспределяется по мере его роста (при необходимости перемещая элементы). Итак, вопрос в том, что Flatten<I>
возвращает для size_hint
?
Реализация Iterator::size_hint
для Flatten<I>
пересылает во внутреннюю структуру FlattenCompat<I>
, которая являетсянемного сложнее, потому что он поддерживает двустороннюю итерацию, но в конечном итоге возвращает (0, None)
, если внешний итератор не был расширен или исчерпан .
Итак, ответ на ваш вопрос: он что-то делаетменее эффективным. А именно (если вы уже не вызывали next
или next_back
на итераторе хотя бы один раз), он создает пустой Vec<T>
и постепенно увеличивает его в соответствии с любой стратегией роста, используемой Vec
(которая не указана, но гарантируется документацией, что O(1)
амортизируется push
).
Это не является искусственным ограничением;это фундаментально для работы Flatten
. Единственный способ предварительно рассчитать размер сплющенного итератора - это исчерпать внешний итератор и сложить все внутренние size_hint
с. Это плохая идея, поскольку она не всегда работает (внутренние итераторы могут не возвращать полезных size_hint
с), а также потому, что вам также нужно найти способ сохранить внутренние итераторы после исчерпания внешнего;не существует решения, которое было бы приемлемо для адаптера итератора общего назначения.
Если вы знаете что-то о своем конкретном итераторе, которое позволяет вам узнать, каким должен быть конечный размер, вы можете зарезервировать выделение самостоятельно, вызвав Vec::with_capacity
и используйте Extend
, чтобы заполнить его из flatten
ed итератора, вместо использования collect
.