rust-Syntax:grund für &mut foo anstelle von &foo in rust, als foo mut deklarierte
Frage
Für eine c-Routine wie
MPI_Comm_rank(MPI_Comm comm, int *rank);
die Rust-Fremdfunktionsschnittstelle könnte folgendermaßen deklariert werden:
extern crate libc;
use libc::{c_int};
#[link(name = "mpi")]
extern {
fn MPI_Comm_rank(mpi_comm: c_int,
rank: *mut c_int);
}
Ich nenne die Bindung so, was funktioniert, aber mich über die Syntax verwirrt hat:
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)}
}
Ich habe es ursprünglich versucht
unsafe {MPI_Comm_rank(MPI_COMM_WORLD, &rank)}
dies führt jedoch zu einem Compilerfehler:
mismatched types: expected `*mut i32` but found `&i32` (values differ in mutability)
Ich habe 'Rang' als mut deklariert, also was gibt es?
Lösung
Sie verschmelzen zwei völlig unterschiedliche Merkmale.
let mut x;
macht eine veränderliche Bindung x
, so dass Sie ändern können, woran x gebunden ist (x = 42
) und für Nicht-Referenztypen, um ihren Inhalt zu ändern (x.y = 42
).Es kontrolliert nicht die Veränderlichkeit der Ziel von Referenzen.
Dies unterscheidet sich von der Art der Referenzen, mit denen Sie es zu tun haben.
&mut T
ist eine veränderliche Referenz und kann dazu gezwungen werden*mut T
.&T
ist eine unveränderliche Referenz erzwungen werden kann*const T
.
Wie die Funktion, die Sie aufrufen, will *mut T
, du musst es passieren a *mut T
oder ein &mut T
; *const T
oder &T
geht nicht.
Natürlich können Sie nur einen veränderlichen Verweis auf veränderliche Daten verwenden, also let x = 42; &mut x
funktioniert nicht so, wie es benötigt wird let mut x
statt let x
, aber das ist immer noch völlig verschieden und Teil von Rusts Regeln über Veränderlichkeit.
Andere Tipps
Ihre Funktion erwartet *mut c_int
zeiger (ein veränderlicher roher Zeiger), und Sie müssen verwenden &mut
betreiber, um es zu erhalten.Sie können jedoch nur nehmen &mut
zeiger auf mut
variablen, daher müssen Sie deklarieren rank
variabel als mut rank
.
Wenn Ihre Funktion erwartet *const c_int
zeiger, den Sie verwenden könnten &
, aber das ist nicht der Fall.