对于像这样的 C 例程

MPI_Comm_rank(MPI_Comm comm, int *rank);
Rust 外部函数接口(interface)可以这样声明:
use libc::c_int; // 0.2.79

#[link(name = "mpi")]
extern "C" {
    fn MPI_Comm_rank(mpi_comm: c_int, rank: *mut c_int);
}
我像这样调用绑定(bind),它有效,但让我对语法感到困惑:
pub static MPI_COMM_WORLD: libc::c_int = 0x44000000;
fn main() {
    let mut rank: c_int = 999999;
    /* but why '&mut rank' and not simply '&rank' ? */
    unsafe { MPI_Comm_rank(MPI_COMM_WORLD, &mut rank) }
}
我最初尝试
unsafe { MPI_Comm_rank(MPI_COMM_WORLD, &rank) }
但这会导致编译器错误:
error[E0308]: mismatched types
  --> src/main.rs:12:44
   |
12 |     unsafe { MPI_Comm_rank(MPI_COMM_WORLD, &rank) }
   |                                            ^^^^^ types differ in mutability
   |
   = note: expected raw pointer `*mut i32`
                found reference `&i32`
我将 'rank' 声明为 mut,那么结果是什么?

最佳答案

您将两个完全不同的功能混为一谈。
let mut x; 生成可变绑定(bind) x ,允许您修改 x 绑定(bind)到的内容 ( x = 42 ) 以及非引用类型修改其内容 ( x.y = 42 )。它不控制引用目标的可变性。

这与您正在处理的引用类型不同。

  • &mut T 是一个可变引用,可以强制转换为 *mut T
  • &T 是一个不可变的引用,可以强制转换为 *const T

  • 由于您正在调用的函数需要 *mut T ,因此您必须将 *mut T&mut T 传递给它; *const T&T 不会。

    可以肯定的是,您只能对可变数据进行可变引用,因此 let x = 42; &mut x 不起作用,因为它需要 let mut x 而不是 let x ,但这仍然是完全不同的,并且是 Rust 关于可变性规则的一部分。

    关于syntax - 当 foo 被声明为可变时,需要 &mut foo 而不是 &foo 的原因是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25091631/

    10-11 22:13