Boas Práticas de Propriedade
Regras para APIs e estruturas de dados que funcionam com o borrow checker em vez de contra ele.
Como Usar Esta Lista
- Aplique durante revisões de design de API antes de publicar um crate.
- Use quando erros de empréstimo se repetirem no mesmo módulo.
- Combine com lints do clippy como
redundant_cloneeneedless_borrow.
A - Formato da API
- Aceite
&str,&[T],&Pathpara entradas somente leitura. Chamadores mantêm a propriedade; menos movimentações. - Retorne valores de propriedade, a menos que zero-copy seja uma vitória medida. Lifetimes mais simples para consumidores.
- Use
impl AsRef<str>em limites com moderação. Conveniência para chamadores; documente a coerção. - Prefira
Cow<'a, T>para texto possivelmente emprestado/possuído. Evita alocação forçada. - Documente quem é o proprietário dos handles retornados. Chamadores precisam saber a responsabilidade de
drop.
B - Mutação e Compartilhamento
- Use métodos
&mut selfpara atualizações no local. Contrato de acesso exclusivo claro. - Alcance a mutabilidade interior somente após falharem refatorações estruturais.
RefCell/Mutexcomo último recurso. - Divida coleções e índices para grafos.
usizeemVecsupera auto-referências. - Evite
Rcaté que a propriedade compartilhada seja necessária. Um único proprietário é mais simples de raciocinar. - Não mantenha locks através de
.await. Use primitivas cientes de async (tokio::sync).
C - Clonagem e Cópia
- Clone em limites, não em loops internos. Perfis antes de otimizar clones.
- Derive
Copyapenas para tipos pequenos, somente de pilha. ArraysCopygrandes são caros. - Use
clone_fromao reutilizar alocação.dst.clone_from(&src)pode reutilizar a capacidade. - Habilite
clippy::redundant_clone. Captura duplicatas desnecessárias na revisão. - Trate
to_owned()comoclone()para clareza. Escolha um estilo por crate.
D - Lifetimes em APIs Públicas
- Minimize parâmetros de lifetime em structs públicas. Cada
'aé um custo cognitivo para os usuários. - Prefira elisão onde o compilador permite. Adicione lifetimes explícitos quando os erros guiarem você.
- Nunca exponha empréstimos de pilha para threads sem threads com escopo. Use capturas de propriedade
'static. - Explique as restrições de lifetime em rustdoc. Mantenedores futuros precisam do porquê.
- Adicione exemplos que compilam em doctests. APIs de lifetime quebram silenciosamente de outra forma.
FAQs
Quantos clones são muitos?
Se a profilaxia mostrar que a clonagem domina, refatore. Caso contrário, a clareza vence nas fronteiras.
Quando `Arc` é apropriado?
Propriedade compartilhada entre threads ou caches de longa duração com múltiplos handles.
APIs de biblioteca devem usar `String` ou `&str`?
Entradas: &str. Saídas: String de propriedade, a menos que o empréstimo da entrada seja intencional e documentado.
Como revisar a propriedade em PRs?
Verifique assinaturas de função, novos Rc/RefCell, clones em loops e unwrap em locks.
`unwrap` aceitável em `RefCell`?
Somente quando invariantes provam que não há empréstimo reentrante - documente o invariante.
Convenções em todo o workspace?
Publique um ADR sobre tipos de string, propriedade de erro e padrões de estado async.
Testando código com muitos empréstimos?
Doctests, Miri para adjacência unsafe, loom para concorrência (avançado).
Newtype para IDs?
Previne a mistura de índices de diferentes registros - vitória barata.
Quando usar `pin`?
Máquinas de estado/auto-referenciais assíncronas - siga os padrões do crate pin, não invente.
Próximos tópicos?
Structs/enums para modelagem, ponteiros inteligentes quando o compartilhamento é real.
Relacionados
- Fundamentos de Propriedade - fundamentos
- Combatendo o Borrow Checker - padrões de refatoração
- Boas Práticas de Ponteiros Inteligentes - regras de
Rc/Arc - Boas Práticas de Structs & Enums - modelagem de dados
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+.