生锈语法:当foo声明为mut时,原因为& mut foo而不是& foo

时间:2014-08-02 04:19:43

标签: syntax rust ffi

对于像

这样的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,那么是什么给出了?

2 个答案:

答案 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指针,则可以使用&,但事实并非如此。