对于像
这样的c例程MPI_Comm_rank(MPI_Comm comm, int *rank);
rust外部函数接口可以这样声明:
extern crate libc;
use libc::{c_int};
#[link(name = "mpi")]
extern {
fn MPI_Comm_rank(mpi_comm: c_int,
rank: *mut c_int);
}
我这样调用绑定,这有效,但让我对语法感到困惑:
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)}
但这会产生编译错误:
mismatched types: expected `*mut i32` but found `&i32` (values differ in mutability)
我宣称'等级'为mut,那么是什么给出了?
答案 0 :(得分:5)
你正在混淆两个完全不同的功能。
let mut x;
生成一个可变绑定x
,允许您修改x绑定的内容(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关于可变性的规则的一部分。
答案 1 :(得分:1)
您的函数需要*mut c_int
指针(一个可变的原始指针),您需要使用&mut
运算符来获取它。但是,您只能将&mut
指针指向mut
变量,因此您需要将rank
变量声明为mut rank
。
如果您的函数需要*const c_int
指针,则可以使用&
,但事实并非如此。