预期引用,发现结构体

5

我正在尝试通过翻译Stepanov和McJones的“程序元素”书中的C++代码来学习Rust。这里是一个简单的代码片段:

extern crate num_bigint;

use num_bigint::BigInt;

pub fn fibonacci_matrix_multiply(x: (&BigInt, &BigInt), y: (&BigInt, &BigInt)) -> (BigInt, BigInt) {
    (x.0 * (y.1 + y.0) + x.1 * y.0, x.0 * y.0 + x.1 * y.1)
}

pub fn power_accumulate_positive(
    mut r: (&BigInt, &BigInt),
    mut a: (&BigInt, &BigInt),
    mut n: i32,
) -> (BigInt, BigInt) {
    loop {
        if n & 1 == 1 {
            r = fibonacci_matrix_multiply(r, a);
            if n == 1 {
                return r;
            }
        }
        a = fibonacci_matrix_multiply(a, a);
        n = n / 2;
    }
}

fn main() {}

以下是错误信息:

error[E0308]: mismatched types
  --> src/main.rs:16:17
   |
16 |             r = fibonacci_matrix_multiply(r, a);
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found struct `num_bigint::BigInt`
   |
   = note: expected type `(&num_bigint::BigInt, &num_bigint::BigInt)`
              found type `(num_bigint::BigInt, num_bigint::BigInt)`

error[E0308]: mismatched types
  --> src/main.rs:18:24
   |
18 |                 return r;
   |                        ^ expected struct `num_bigint::BigInt`, found reference
   |
   = note: expected type `(num_bigint::BigInt, num_bigint::BigInt)`
              found type `(&num_bigint::BigInt, &num_bigint::BigInt)`

error[E0308]: mismatched types
  --> src/main.rs:21:13
   |
21 |         a = fibonacci_matrix_multiply(a, a);
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found struct `num_bigint::BigInt`
   |
   = note: expected type `(&num_bigint::BigInt, &num_bigint::BigInt)`
              found type `(num_bigint::BigInt, num_bigint::BigInt)`

我知道我正在返回一个元组结构,尝试将其分配给一个引用元组,但我不知道如何解决这个问题。


简而言之,引用和非引用是不同的类型,就像C++中一样。如果您想存储一个引用或拥有的值,那么需要使用“Cow”。直接(丑陋)解决方案使用“Cow” - Shepmaster
1个回答

4

你为什么不能按值而非按引用获取BigInts?这将消除所有借用检查器错误。除非克隆BigInts是明显且经过衡量的瓶颈,否则通过引用传递不会更快,而且不太符合人体工程学。

以下是一个可行的解决方案,它不使用引用(而是克隆值)

extern crate num_bigint;

use num_bigint::BigInt;

pub fn fibonacci_matrix_multiply(x: (BigInt, BigInt), y: (BigInt, BigInt)) -> (BigInt, BigInt) {
    (&x.0 * (&y.1 + &y.0) + &x.1 * &y.0, x.0 * y.0 + x.1 * y.1)
}

pub fn power_accumulate_positive(
    mut r: (BigInt, BigInt),
    mut a: (BigInt, BigInt),
    mut n: i32,
) -> (BigInt, BigInt) {
    loop {
        if n & 1 == 1 {
            r = fibonacci_matrix_multiply(r, a.clone());
            if n == 1 {
                return r;
            }
        }
        a = fibonacci_matrix_multiply(a.clone(), a);
        n = n / 2;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接