Текущая ошибка, с которой вы столкнулись, находится здесь:
let iterbox:Box<Iterator<Item = usize>> = Box::new(small_data.iter());
Вы заявляете, что вам нужен итератор, который возвращает usize
элементов, но small_data.iter()
- это итератор, который возвращает ссылки наusize
предметов (&usize
).Вот почему вы получаете ошибку «ожидаемая ссылка найдена».usize
- это небольшой тип, который можно клонировать, поэтому вы можете просто использовать адаптер итератора .cloned()
для создания итератора, который фактически возвращает размер.
let iterbox: Box<Iterator<Item = usize>> = Box::new(small_data.iter().cloned());
Как только вы преодолеете это препятствие, возникает следующая проблемаявляется то, что итератор, возвращенный над small_data
, содержит ссылку на small_data
.Поскольку sum_squares_plus
определено для принятия Box<Iterator<Item = usize>>
, в этой сигнатуре подразумевается, что объект черты Iterator
в блоке имеет время жизни 'static
.Итератор, который вы предоставляете, не делает этого, потому что он занимает small_data
.Чтобы исправить это, вам нужно настроить определение sum_squares_plus
на
fn sum_squares_plus<'a>(iter: Box<Iterator<Item = usize> + 'a>, x: usize) -> usize
Обратите внимание на аннотации 'a
времени жизни.Затем код должен компилироваться, но если нет каких-либо ограничений, кроме того, что четко определено здесь, более идиоматичным и эффективным подходом было бы избегать использования объектов-признаков и связанных распределений.Приведенный ниже код должен работать с использованием статической диспетчеризации без каких-либо объектов-черт.
fn sum_squares_plus<I: Iterator<Item = usize>>(iter: I, x: usize) -> usize {
let mut ans: usize = 0;
for i in iter {
ans += i * i;
}
ans + x
}
fn main() {
// Pretend this is an expensive operation that I don't want to repeat five times
let small_data: Vec<usize> = (0..10).collect();
for x in 0..5 {
println!("{}: {}", x, sum_squares_plus(small_data.iter().cloned(), x));
}
// 0..100 is more than 0..10 and I'm only using it once,
// so I want to 'stream' it instead of storing it all in memory
let x = 55;
println!("{}: {}", x, sum_squares_plus(Box::new(0..100), x));
}