sintaxe de ferrugem:razão para &mut foo em vez de &foo enferrujado quando foo declarou mut

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

  •  02-01-2020
  •  | 
  •  

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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top