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<T> where
T : Zero + One + Add + Copy {
curr : T,
next : T,
}
impl<T> Fibonacci<T> where
T : Zero + One + Add + Copy{
pub fn new() -> Fibonacci<T> {
Fibonacci {
curr : T::zero(),
next : T::one(),
}
}
}
impl<T> Iterator for Fibonacci<T> where
T : Zero + One + Add + Copy {
type Item = T;
fn next(&mut self) -> Option<T> {
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<u32> = Fibonacci::new();
assert_eq!(f.next(), Some(1));
let mut next_val = 1;
let mut curr_val = 0;
for i in Fibonacci::<u32>::new().take(4) {
let c = next_val;
next_val = curr_val + next_val;
curr_val = c;
assert_eq!(i, next_val);
}
}
}
fib_trait.rs
(the module name isfib_trait
) and I have imported the module insrc/lib.rs
so that cargo can see it. You can also get it work the way you have done, just rename or remove the module wrapper inlib.rs
\$\endgroup\$next(&mut self)
takes in a reference and there is no way to add values without copying!? Posting the question here was one way to verify this assumption and to check if I was missing something :) \$\endgroup\$