Implement a generic Fibonacci sequence in Rust without using Copy trait I'm trying to learn Rust and am a beginner. How does one go about implementing a generic version of the Fibonacci sequence without using Copy trait in Rust? My code is given below. 

I had to use Copy trait, otherwise the compiler would complain


  cannot move out of borrowed content [E0507]


in the method next() (everywhere I have borrowed from self). I understand the error, but I'm not sure how this could be done without copying. Also, other comments and observations are welcome!

lib.rs

pub mod fib_trait;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}


fib_trait.rs

extern crate num;

pub mod fib_trait {

    use fib_trait::num::traits::*;
    use std::ops::Add;

    #[derive(Clone, Copy)]
    pub struct Fibonacci&lt;T&gt; where
    T : Zero + One + Add + Copy {
        curr : T,
        next : T,
    }

    impl&lt;T&gt; Fibonacci&lt;T&gt; where 
    T : Zero + One + Add  + Copy{
        pub fn new() -&gt; Fibonacci&lt;T&gt; {
            Fibonacci {
                curr : T::zero(),
                next : T::one(),
            }
        }
    }

    impl&lt;T&gt; Iterator for Fibonacci&lt;T&gt; where
    T : Zero + One + Add + Copy {
        type Item = T;

        fn next(&amp;mut self) -&gt; Option&lt;T&gt; {
            let c : T = self.next;
            self.next = self.next + self.curr;
            self.curr = c;
            let n : T = self.next;
            Some(n)
        }
    }

    #[test]
    pub fn fib_test() {
        let mut f : Fibonacci&lt;u32&gt; = Fibonacci::new();
        assert_eq!(f.next(), Some(1));

        let mut next_val = 1;
        let mut curr_val = 0; 
        for i in Fibonacci::&lt;u32&gt;::new().take(4) {
            let c = next_val;
            next_val = curr_val + next_val;
            curr_val = c;
            assert_eq!(i, next_val);
        }
    }
}
You can use Clone instead of Copy. This requires adding .clone() calls where the compiler did a copy when the Copy bound was present.

extern crate num;

pub mod fib_trait {
    use num::traits::*;
    use std::ops::Add;

    #[derive(Clone, Copy)]
    pub struct Fibonacci&lt;T&gt;
        where T: Zero + One + Add + Clone
    {
        curr: T,
        next: T,
    }

    impl&lt;T&gt; Fibonacci&lt;T&gt;
        where T: Zero + One + Add + Clone
    {
        pub fn new() -&gt; Fibonacci&lt;T&gt; {
            Fibonacci {
                curr: T::zero(),
                next: T::one(),
            }
        }
    }

    impl&lt;T&gt; Iterator for Fibonacci&lt;T&gt;
        where T: Zero + One + Add + Clone
    {
        type Item = T;

        fn next(&amp;mut self) -&gt; Option&lt;T&gt; {
            let c: T = self.next.clone();
            self.next = self.next.clone() + self.curr.clone();
            self.curr = c;
            let n: T = self.next.clone();
            Some(n)
        }
    }

    #[test]
    pub fn fib_test() {
        let mut f: Fibonacci&lt;u32&gt; = Fibonacci::new();
        assert_eq!(f.next(), Some(1));

        let mut next_val = 1;
        let mut curr_val = 0;
        for i in Fibonacci::&lt;u32&gt;::new().take(4) {
            let c = next_val;
            next_val = curr_val + next_val;
            curr_val = c;
            assert_eq!(i, next_val);
        }
    }
}


We can eliminate the clones on the addition by requiring and using addition on references instead of direct values. for&lt;'a&gt; introduces a higher-rank trait bound &ndash; we need this because we want &amp;'a T to implement Add&lt;Output=T&gt;, whatever the lifetime 'a is.

extern crate num;

pub mod fib_trait {
    use num::traits::*;
    use std::ops::Add;

    #[derive(Clone, Copy)]
    pub struct Fibonacci&lt;T&gt;
        where T: Zero + One + Clone,
              for&lt;'a&gt; &amp;'a T: Add&lt;Output=T&gt;
    {
        curr: T,
        next: T,
    }

    impl&lt;T&gt; Fibonacci&lt;T&gt;
        where T: Zero + One + Clone,
              for&lt;'a&gt; &amp;'a T: Add&lt;Output=T&gt;
    {
        pub fn new() -&gt; Fibonacci&lt;T&gt; {
            Fibonacci {
                curr: T::zero(),
                next: T::one(),
            }
        }
    }

    impl&lt;T&gt; Iterator for Fibonacci&lt;T&gt;
        where T: Zero + One + Clone,
              for&lt;'a&gt; &amp;'a T: Add&lt;Output=T&gt;
    {
        type Item = T;

        fn next(&amp;mut self) -&gt; Option&lt;T&gt; {
            let c: T = self.next.clone();
            self.next = &amp;self.next + &amp;self.curr;
            self.curr = c;
            let n: T = self.next.clone();
            Some(n)
        }
    }

    #[test]
    pub fn fib_test() {
        let mut f: Fibonacci&lt;u32&gt; = Fibonacci::new();
        assert_eq!(f.next(), Some(1));

        let mut next_val = 1;
        let mut curr_val = 0;
        for i in Fibonacci::&lt;u32&gt;::new().take(4) {
            let c = next_val;
            next_val = curr_val + next_val;
            curr_val = c;
            assert_eq!(i, next_val);
        }
    }
}




Also, note the stylistic changes I made above:


line break before where
indent where clause
no space before :