Ambiente : rustc 1.82.0 (f6e511eec 2024-10-15)
Pergunta: Desreferenciamento vs. Empréstimo Direto em Rust
Estou confuso sobre a diferença entre *&T
e T
em empréstimo. O código a seguir compila com let b = &mut *a
, mas falha com let b = &mut x
. Por que *a
se comporta diferentemente de x
neste contexto?
Além disso, descomentar a última linha ( *b = ...
) causa o erro:
não pode atribuir
*a
porque é emprestado
fn annoying_borrow() {
let mut x = Box::new(1);
let a = &mut x;
let b = &mut *a;
// let b = &mut x; // error: cannot borrow `x` as mutable more than once at a time
*a = Box::new(2);
// *b = Box::new(3); // error: `*a` is assigned to here but it was already borrowed
}
Usar the *a
em vez de the x
here implica ainda mais na sutil diferença entre eles? Emmm, o que eu realmente quero explorar não é a diferença entre *a
and x
, mas as regras de empréstimo no sistema de tipos Rust (compilador).
Fundo:
Consultei Programming Rust, 2ª edição (Capítulo 5), mas não consigo compreender totalmente esse conhecimento:
O acesso compartilhado é somente leitura.
Valores emprestados por referências compartilhadas são somente leitura. Ao longo da vida útil de uma referência compartilhada, nem seu referente, nem nada alcançável daquele referente, pode ser alterado por nada. Não existem referências mutáveis vivas para nada naquela estrutura, seu proprietário é mantido somente leitura, e assim por diante. Está realmente congelado.
Acesso mutável é acesso exclusivo.
Um valor emprestado por uma referência mutável é alcançável exclusivamente por meio dessa referência. Ao longo do tempo de vida de uma referência mutável, não há outro caminho utilizável para seu referente ou para qualquer valor alcançável a partir daí. As únicas referências cujos tempos de vida podem se sobrepor a uma referência mutável são aquelas que você pega emprestado da própria referência mutável.
Gostaria de saber se há alguma explicação unificada e detalhada sobre empréstimos em Rust. Talvez houvesse um conjunto claro de regras sobre empréstimos em Rust, mas com o compilador relaxando continuamente as restrições de sintaxe (para facilitar a codificação em certos cenários?), as regras atuais são mais caóticas?