我尝试使用Rust by Example's Iterator section遵循 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));
}

上面的代码无法编译:

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

我不确定这是否是由于BigUint类型不是原始类型,因此它没有Copy特性。如何修改迭代器以使其与FibState结构一起使用?

最佳答案

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没有实现Copy,但是 Add 特性通过值接受两个参数。 BigUint也为引用实现了Add,因此您可以取值的引用。
  • 我们想用b的下一个值替换b的当前值,但是我们需要保留旧值。我们可以为此使用 mem::replace
  • 将旧的b值分配给a很简单。
  • 现在,我们希望返回a中的值,因此我们需要 clone 整个值。



  • 某些东西是原始的,而某些东西实现了Copy的特性则彼此无关。用户类型可以实现Copy,而某些原语不实现Copy

    也可以看看:
  • How to swap two variables?
  • How do I implement the Add trait for a reference to a struct?
  • Operator overloading by value results in use of moved value
  • 10-07 16:09