sintaxe de ferrugem:razão para &mut foo em vez de &foo enferrujado quando foo declarou mut
Pergunta
Para uma rotina c como
MPI_Comm_rank(MPI_Comm comm, int *rank);
a interface da função externa de ferrugem poderia ser declarada assim:
extern crate libc;
use libc::{c_int};
#[link(name = "mpi")]
extern {
fn MPI_Comm_rank(mpi_comm: c_int,
rank: *mut c_int);
}
Eu chamo a ligação assim, o que funciona, mas me deixou confuso sobre a sintaxe:
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)}
}
Eu originalmente tentei
unsafe {MPI_Comm_rank(MPI_COMM_WORLD, &rank)}
mas isso dá um erro de compilador:
mismatched types: expected `*mut i32` but found `&i32` (values differ in mutability)
Eu declarei 'classificação' como mut, então o que acontece?
Solução
Você está combinando dois recursos completamente distintos.
let mut x;
faz uma ligação mutável x
, permitindo que você modifique a que x está vinculado (x = 42
) e para tipos sem referência modificar seu conteúdo (x.y = 42
).Não controla a mutabilidade do alvo de referências.
Isso é diferente do tipo de referência com a qual você está lidando.
&mut T
é uma referência mutável e pode ser coagida a*mut T
.&T
é uma referência imutável pode ser coagido a*const T
.
Como a função que você está chamando deseja *mut T
, você deve passar um *mut T
ou um &mut T
; *const T
ou &T
não vai fazer.
Com certeza, você só pode usar uma referência mutável para dados mutáveis, então let x = 42; &mut x
não funciona como precisa let mut x
em vez de let x
, mas isso ainda é totalmente distinto e faz parte das regras de Rust sobre mutabilidade.
Outras dicas
Sua função espera *mut c_int
ponteiro (um ponteiro bruto mutável), e você precisa usar &mut
operador para obtê-lo.No entanto, você só pode levar &mut
ponteiro para mut
variáveis, portanto você precisa declarar rank
variável como mut rank
.
Se sua função esperava *const c_int
ponteiro, você seria capaz de usar &
, mas este não é o caso.