Preview de Propriedade
Propriedade é o modelo de memória central do Rust: um proprietário por valor, movimentações transferem responsabilidade e empréstimos permitem acesso temporário sob regras de tempo de compilação. Esta página apresenta as ideias antes da seção de Propriedade.
Receita
fn main() {
let s = String::from("hello");
let t = s; // move
// println!("{s}"); // erro: movido
let len = measure(&t);
println!("{t} tem o comprimento {len}");
}
fn measure(text: &String) -> usize {
text.len()
}Quando usar isto: Sempre que você passar dados entre funções, armazená-los em structs ou compartilhá-los entre threads - as regras de propriedade se aplicam em todos os lugares.
Exemplo de Trabalho
fn append(mut s: String, suffix: &str) -> String {
s.push_str(suffix);
s
}
fn print_both(first: &str, second: &str) {
println!("{first} {second}");
}
fn main() {
let greeting = String::from("Hello");
let full = append(greeting, ", Rust!");
let slice: &str = &full;
print_both(slice, "welcome.");
}O que isso demonstra:
appendassume a propriedade degreetinge retornaStringatualizado&strempresta dados de string sem possuí-losStringé coagido para&strviaDeref(coerção de deref)- Funções sinalizam a transferência de propriedade em suas assinaturas
Mergulho Profundo
Como Funciona
- Dados na pilha com
Copyduplicam na atribuição (i32,bool,char) - Tipos proprietários do heap (
String,Vec) movem na atribuição - Quando um proprietário sai do escopo,
dropé executado automaticamente - Referências (
&T,&mut T) são visualizações emprestadas com limites de tempo de vida
Movimentação vs Cópia
let a = 5;
let b = a; // Cópia - ambos válidos
let v1 = vec![1, 2];
let v2 = v1; // Movimentação - v1 inválidoRegras de Empréstimo (Resumo)
- Qualquer número de
&Tou exatamente um&mut Tpor vez - Referências não devem sobreviver ao proprietário
- Corridas de dados são prevenidas em tempo de compilação
Pilha vs Heap (Preview)
let x = 42; // pilha
let s = String::from("x"); // ponteiro + capacidade + len na pilha, bytes no heapArmadilhas
- Usar um valor após a movimentação - Erro clássico de iniciante com
String. Correção: Clone (s.clone()) se precisar de uma duplicata, ou empreste em vez disso. - Assumir propriedade quando o empréstimo é suficiente -
fn print(s: String)força os chamadores a desistirem da string. Correção: Use&strou&String. - Múltiplos
&mutpara os mesmos dados - Erro de compilação. Correção: Reestruture escopos, useRefCellpara mutabilidade interna single-threaded, ou divida campos. - Retornar referência para local -
fn bad() -> &Stringnão pode funcionar. Correção: Retorne valor próprio ou receba entrada por referência com tempo de vida vinculado à entrada. - Clonar para silenciar o verificador de empréstimo - Funciona, mas esconde problemas de design. Correção: Refatore a API para emprestar ou use
Cow.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
Empréstimo &T | Acesso somente leitura | O chamador deve manter a propriedade para o seu tempo de vida de retorno |
Clone | Duplicata barata necessária | Caminho crítico com dados grandes |
Rc/Arc | Propriedade compartilhada | Proprietário único e claro existe |
Cow<'a, T> | Talvez empreste, talvez possua | A propriedade é sempre clara |
FAQs
Por que Rust não tem um coletor de lixo?
Propriedade e tempos de vida liberam memória deterministicamente em tempo de compilação para a maioria do código, com custo zero de GC em tempo de execução.
Quais tipos são `Copy`?
Escalares, tuplas/arrays de tipos Copy, e tipos explicitamente marcados como Copy. String e Vec não são Copy.
Posso optar por não usar movimentações?
Clone explicitamente. Não há cópia implícita para tipos não-Copy.
O que é `Drop`?
Um trait executado automaticamente quando um valor sai do escopo. String libera memória do heap em drop.
Passar para uma função sempre move?
Passar por valor move. Passar por referência &T empresta sem mover a propriedade.
Structs podem possuir outros valores?
Sim. Campos são possuídos como variáveis locais. A struct é a proprietária de seus campos.
O que é um slice?
Uma visualização emprestada em dados contíguos: &[T] ou &str. Slices não possuem memória.
Propriedade é lenta?
Movimentações são cópias de ponteiros para tipos de heap. Nenhuma contagem de referência a menos que você escolha Rc/Arc.
Como a propriedade interage com `async`?
Dados possuídos são movidos para futures. Send/Sync vincula estado compartilhado entre tarefas (veja a seção Concorrência).
Onde está o guia completo de propriedade?
Veja a seção Propriedade começando com Noções Básicas de Propriedade.
Relacionados
- Referências e Slices - mecânicas de empréstimo
- Noções Básicas de Propriedade - mergulho profundo
- Semântica de Movimentação e Cópia -
Copy/Clone - Empréstimos e Referências -
&vs&mut
Versões da Pilha: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.