el óxido de sintaxis:la razón para &mut foo en lugar de &foo en rust cuando foo declarado mut
Pregunta
Para una rutina de c como
MPI_Comm_rank(MPI_Comm comm, int *rank);
la roya de la función externa de la interfaz podría ser declarado como este:
extern crate libc;
use libc::{c_int};
#[link(name = "mpi")]
extern {
fn MPI_Comm_rank(mpi_comm: c_int,
rank: *mut c_int);
}
Yo llamo a la unión, como este, que funciona, pero me dejó perplejo acerca de la sintaxis:
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)}
}
Originalmente se trató de
unsafe {MPI_Comm_rank(MPI_COMM_WORLD, &rank)}
pero esto da un error del compilador:
mismatched types: expected `*mut i32` but found `&i32` (values differ in mutability)
Yo he declarado 'rango' como mut, así que ¿por qué?
Solución
Estás mezclando dos completamente distintas características.
let mut x;
hace un mutable de unión x
, permitiéndole modificar lo que x está obligado a (x = 42
) y para los no-tipos de referencia para modificar su contenido (x.y = 42
).No control de la mutabilidad de la objetivo de referencias.
Esto es diferente del tipo de referencias que se está tratando.
&mut T
es un mutable de referencia y puede ser obligado a*mut T
.&T
es una inmutable de referencia puede ser obligado a*const T
.
Como la función que se quiere llamar *mut T
, usted debe pasar un *mut T
o un &mut T
; *const T
o &T
no va a hacer.
Para estar seguro, usted sólo puede tener un mutable referencia a datos mutables, por lo que let x = 42; &mut x
no funciona como necesidades let mut x
en lugar de let x
, pero que sigue siendo completamente distinto, y es una parte de la Roya de la normativa sobre mutabilidad.
Otros consejos
Su función espera *mut c_int
puntero (mutables raw puntero), y necesita utilizar &mut
operador para obtenerlo.Sin embargo, sólo puede tomar &mut
puntero a mut
las variables, por lo tanto es necesario declarar rank
variable como mut rank
.
Si su función de espera *const c_int
puntero, usted sería capaz de utilizar &
, pero este no es el caso.