I'll start directly with the code sample (has a num-traits dependency)
use num_traits::NumAssign;
pub trait PartialSums: Iterator + Sized {
type SumIterator;
fn sums(self) -> Self::SumIterator;
}
// T stands for item in I and RetVal should be a dereferenced type of T in a case of &T
// But for now RetVal = T
type SumIter<T, I, RetVal> = std::iter::Scan<I, RetVal, fn(&mut RetVal, T) -> Option<RetVal>>;
impl<T, I> PartialSums for I
where
T: NumAssign + Copy,
I: Iterator<Item = T>,
{
type SumIterator = SumIter<Self::Item, Self, Self::Item>;
fn sums(self) -> Self::SumIterator {
self.scan(T::zero(), |s, x| {
*s += x;
Some(*s)
})
}
}
Here I try to create an iterator adapter, that yields partial sums of the sequence. The problem is, I want it to work with both owned and borrowed numbers (I prefer to say it by copy and by ref). If I try to use Borrow or AsRef I got into trouble -- AsRef isn't implemented for numeric primitives, and Borrow doesn't allow me to make constraints about underlying type when arg is passed by ref (I guess I use it wrong, but I run through docs, the book and samples and still have no idea how to use it properly). How can I make this adapter work with numbers both by ref and by copy? The simple snippet should work for me too, just need to get a general idea. For example:
fn add_two<T: Num>(v: T) -> T {
v + v
}
How should I change this function in order to let the following work:
let five: i32 = 5;
add_two(five);
add_two(&five);