sintassi della ruggine:motivo di &mut foo invece di &foo in ruggine quando foo ha dichiarato mut
Domanda
Per una routine c come
MPI_Comm_rank(MPI_Comm comm, int *rank);
l'interfaccia della funzione Rust Foreign potrebbe essere dichiarata in questo modo:
extern crate libc;
use libc::{c_int};
#[link(name = "mpi")]
extern {
fn MPI_Comm_rank(mpi_comm: c_int,
rank: *mut c_int);
}
Chiamo l'associazione in questo modo, che funziona, ma mi ha lasciato perplesso sulla sintassi:
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)}
}
Inizialmente ho provato
unsafe {MPI_Comm_rank(MPI_COMM_WORLD, &rank)}
ma questo dà un errore del compilatore:
mismatched types: expected `*mut i32` but found `&i32` (values differ in mutability)
Ho dichiarato 'rank' come mut, quindi cosa succede?
Soluzione
Stai fondendo due caratteristiche completamente distinte.
let mut x;
crea un legame mutevole x
, permettendoti di modificare ciò a cui x è legato (x = 42
) e per i tipi non di riferimento per modificarne il contenuto (x.y = 42
).Non controlla la mutabilità del bersaglio di riferimenti.
Questo è diverso dal tipo di riferimenti con cui hai a che fare.
&mut T
è un riferimento mutabile e può essere utilizzato con la forza*mut T
.&T
è un riferimento immutabile a cui può essere costretto*const T
.
Come vuole la funzione che stai chiamando *mut T
, devi passarlo a *mut T
o a &mut T
; *const T
O &T
non lo farà.
A dire il vero, puoi solo fare riferimento mutabile a dati mutabili, quindi let x = 42; &mut x
non funziona come dovrebbe let mut x
invece di let x
, ma questo è ancora del tutto distinto e fa parte delle regole di Rust sulla mutabilità.
Altri suggerimenti
La tua funzione si aspetta il puntatore *mut c_int
(un puntatore RAW mutabile) e è necessario utilizzare l'operatore &mut
per ottenerlo.Tuttavia, è possibile prendere solo il puntatore &mut
per le variabili mut
, quindi è necessario dichiarare la variabile rank
come mut rank
.
Se la funzione prevista il puntatore *const c_int
, potresti utilizzare &
, ma questo non è il caso.