Reputation: 609
I tried to follow the iterator approach described in Rust by Example's Iterator section with BigUint
:
extern crate num_bigint;
use num_bigint::{BigUint, ToBigUint};
struct FibState {
a: BigUint,
b: BigUint,
}
impl Iterator for FibState {
type Item = BigUint;
fn next(&mut self) -> Option<BigUint> {
let b_n = self.a + self.b;
self.a = self.b;
self.b = b_n;
Some(self.a)
}
}
fn fibs_0() -> FibState {
FibState {
a: 0.to_biguint().unwrap(),
b: 1.to_biguint().unwrap(),
}
}
fn fib2(n: usize) -> BigUint {
if n < 2 {
n.to_biguint().unwrap()
} else {
fibs_0().skip(n - 1).next().unwrap()
}
}
fn main() {
println!("Fib1(300) = {}", fib2(300));
}
The above code does not compile:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:13:19
|
13 | let b_n = self.a + self.b;
| ^^^^ cannot move out of borrowed content
error[E0507]: cannot move out of borrowed content
--> src/main.rs:13:28
|
13 | let b_n = self.a + self.b;
| ^^^^ cannot move out of borrowed content
error[E0507]: cannot move out of borrowed content
--> src/main.rs:14:18
|
14 | self.a = self.b;
| ^^^^ cannot move out of borrowed content
error[E0507]: cannot move out of borrowed content
--> src/main.rs:16:14
|
16 | Some(self.a)
| ^^^^ cannot move out of borrowed content
I am not sure if it is due to the BigUint
type is not primitive thus it does not have the Copy
trait. How can I modify the iterator to make it works with the FibState
struct?
Upvotes: 0
Views: 151
Reputation: 431669
fn next(&mut self) -> Option<BigUint> {
let b_next = &self.a + &self.b;
let b_prev = std::mem::replace(&mut self.b, b_next);
self.a = b_prev;
Some(self.a.clone())
}
BigUint
does not implement Copy
, but the Add
trait takes both arguments by value. BigUint
implements Add
for references as well, so you can take references of the values instead.
We would like to replace the current value of b
with the next value of b
, but we need to keep the old value. We can use mem::replace
for that.
Assigning the old b
value to a
is straightforward.
Now we wish to return the value in a
, so we need to clone
the entire value.
BigUint
type is not primitive thus it does not have theCopy
trait
Something being a primitive and something implementing the Copy
trait have nothing to do with each other. User types can implement Copy
and some primitives do not implement Copy
.
See also:
Upvotes: 1