0

I've looked around Google and SO for an answer to this, but I couldn't find one. I'm trying to understand iterators, so I can use them as parameters rather than taking a Vec or some other concrete collection. In this example, I'm using floats.

I know sums can be computed using the standard library. I'm looking to understand how to use IntoIterators using this alternate implementation.

fn sample_size_sum<T, I>(values: &mut I, is_sample: bool) -> (u32, T)
    where I: IntoIterator<Item = T> + std::iter::FromIterator<T>, T: num::Float + std::ops::AddAssign + Copy
{
    let mut it = values.into_iter();
    let mut sum: T = num::Float::nan();
    let mut sample_size = 0;
    let mut first = true;

    while let Some(value) = it.next()
    {
        if !value.is_nan()
        {
            sample_size += 1;
            if first
            {
                sum = value;
                first = false;
            }
            else
            {
                sum += value;
            }
        }
    }

    if is_sample && sample_size > 0
    {
        sample_size -= 1;
    }

    return (sample_size, sum);
}

fn main() 
{
    let mut numbers = vec![1.0, 2.0, 3.0, std::f64::NAN, 5.0];
    let (sample_size, sum) = sample_size_sum(&mut numbers, false);
}

The compiler returns the following on the call to into_iter().

cannot move out of `*values` which is behind a mutable reference(E0507)

Does this mean the Vec object owns the iterator which is being moved to my function's scope? I've seen some examples of lifetime syntax which tied the lifetime of parameters and return values together, but I'm not sure what to do with this local variable. I'd appreciate some help.

  • While that does compile, it moves ownership of the vector to sample_size_sum's scope; making it invalid later in main. That was why I was trying to use references. Is there any way to do this without moving ownership? – TheCodeFiend Mar 14 '20 at 01:38
  • Thanks. I'm a bit confused by the syntax. The values parameter is of type I (not &I), yet it accepts a reference. Is that inferred from some other syntax? I appreciate the answers. I'm still learning. I'm using IntoIterator as I read it was more flexible. I could make more than one iteration like if a function calls another for some preprocessing. Correct me if I'm wrong, but if I only had an Iterator, I wouldn't be able to do that. Of course, there would be certain situations where I wouldn't want multiple passes to be possible. If you have other ideas or links, I'd love to read them. – TheCodeFiend Mar 14 '20 at 03:28
  • Edit: Sorry, I misread your comment on FromIterator. It was added at one point while I was trying to get things to compile, and it removed some errors stating I was missing that very trait. The code has been morphing since. I guess I don't need it. :-) – TheCodeFiend Mar 14 '20 at 03:36
  • https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=00ca6c48e28fca165f400ce878de8776 when you say to rust I want something that implement an iterator, it can be anything, [vector implement intoiterator for &Vec](https://doc.rust-lang.org/std/vec/struct.Vec.html#impl-IntoIterator) ;) see https://stackoverflow.com/questions/34733811/what-is-the-difference-between-iter-and-into-iter, https://stackoverflow.com/questions/34969902/how-to-write-a-rust-function-that-takes-an-iterator – Stargateur Mar 14 '20 at 13:13

0 Answers0