Understanding the trait std::iter::Sum<T>

The following code can compile(playground):

use std::iter::Sum;


pub trait AggFunc {
    type T;
    fn size(&self) -> usize;
    fn min(&self) -> Self::T;
    fn max(&self) -> Self::T;
    fn sum(&self) -> Self::T;
    fn mean(&self) -> Self::T;
}

impl<E> AggFunc for [E]
where 
    for<'l> E: PartialOrd + Copy + Sum<&'l E> + From<u16> + std::ops::Div<Output = E>,
{
    type T = E;
    fn size(&self) -> usize { self.len() }
    fn min(&self) -> Self::T {
        *self.iter().min_by(|a, b| a.partial_cmp(b).unwrap()).unwrap()
    }
    fn max(&self) -> Self::T {
        *self.iter().max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap()
    }
    fn sum(&self) -> Self::T {
        self.iter().sum()
    }
    fn mean(&self) -> Self::T {
        let len: E = E::from(self.size() as u16);
        self.sum() / len
    }
}

But I can not understand the trait bound about Sum. Why I can not just write the trait implementation like this:

impl<E> AggFunc for [E]
where 
    E: PartialOrd + Copy + Sum<E> + From<u16> + std::ops::Div<Output = E>,
{
    type T = E;
    fn sum(&self) -> Self::T {
        self.iter().sum().copy()
    }
}

When I call self.iter().sum().copy(), it returns a value of type E with no lifetime.

Besides, I'm just to trying to get to this:

data1: Vec<f32> = vec![1., 2., 3.];
data2: Vec<f64> = vec![2., 2., 3.];
data3: Vec<i32> = vec![1, 2, 3];

data1.mean();
data2.mean();
data3.mean();

Which bounds I can remove to make the implementation more brief?

The following will work:

 impl<E> AggFunc for [E]
 where 
-    for<'l> E: PartialOrd + Copy + Sum<&'l E> + From<u16> + std::ops::Div<Output = E>,
+    E: PartialOrd + Copy + Sum<E> + From<u16> + std::ops::Div<Output = E>,
 {
     type T = E;
     /* … */
     fn sum(&self) -> Self::T {
-        self.iter().sum()
+        self.iter().copied().sum()
     }
     /* … */
 }

(Playground)

The reason is that .iter() gives you references. You can use Iterator::copied to get the owned values (if Copy is implemented, which it is).

2 Likes

Misconception #4: my code has no lifetimes

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.