синтаксис rust:причина &mut foo вместо &foo в rust, когда foo объявил mut

StackOverflow https://stackoverflow.com//questions/25091631

  •  02-01-2020
  •  | 
  •  

Вопрос

Для процедуры 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, так что же это дает?

Это было полезно?

Решение

Вы смешиваете две совершенно разные черты.

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 о изменчивости.

Другие советы

Ваша функция ожидает *mut c_int указатель (изменяемый необработанный указатель), и вам нужно использовать &mut оператор, чтобы получить его.Однако вы можете взять только &mut указатель на mut переменные, следовательно, вам нужно объявить rank переменная как mut rank.

Если ваша функция ожидалась *const c_int указатель, вы могли бы использовать &, но это не тот случай.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top