rust-Syntax:grund für &mut foo anstelle von &foo in rust, als foo mut deklarierte

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

  •  02-01-2020
  •  | 
  •  

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?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top