How to avoid excessive cloning in rust?

I am trying to learn Rust, and, like many others, I went on to write a Fibonacci sequence iterator for practice. My first pass used u32 and worked fine, so I decided to try creating a generic version. This is my result:

 use num::Integer; use std::ops::Add; pub struct Fibonacci<T: Integer + Add + Clone> { nth: T, n_plus_one_th: T, } impl<T: Integer + Add + Clone> Iterator for Fibonacci<T> { type Item = T; fn next(&mut self) -> Option<T> { let temp = self.nth.clone(); self.nth = self.n_plus_one_th.clone(); self.n_plus_one_th = temp.clone() + self.n_plus_one_th.clone(); Some(temp) } } impl<T: Integer + Add + Clone> Fibonacci<T> { pub fn new() -> Fibonacci<T> { Fibonacci { nth: T::one(), n_plus_one_th: T::one(), } } } 

I tested this with u32 and num::BigUint and it works great. However, I am worried about cloning in the next method. In particular, I don't understand why I should clone during the add phase.

I suspect there is a better way to write this using some of Rust's more advanced reference concepts, but so far I have not understood this.

+5
source share
1 answer

The solution is to use the where clause like this:

 extern crate num; use num::One; use std::ops::Add; pub struct Fibonacci<T> { nth: T, n_plus_one_th: T, } impl<T> Fibonacci<T> where T: One { pub fn new() -> Fibonacci<T> { Fibonacci { nth: T::one(), n_plus_one_th: T::one(), } } } impl<T> Iterator for Fibonacci<T> where for<'a> &'a T: Add<&'a T, Output = T> { type Item = T; fn next(&mut self) -> Option<T> { use std::mem::swap; let mut temp = &self.nth + &self.n_plus_one_th; swap(&mut self.nth, &mut temp); swap(&mut self.n_plus_one_th, &mut self.nth); Some(temp) } } 

In particular, the sentence for<'a> &'a T: Add<&'a T, Output=T> reads as "for any lifetime 'a , &'a T should implement Add with RHS &'a T and Output=T That is, you can add two &T to get a new T

However, the only remaining problem is shuffling the values ​​around, which can be done using swap .

I also took the liberty of simplifying the restrictions elsewhere (you only need One , not Integer ).

+7
source

Source: https://habr.com/ru/post/1260792/


All Articles