对于像这样的 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/