Ergonomia de Deref e wrappers
Faça os wrappers parecerem nativos.
Ergonomia de Deref e wrappers é uma aula grátis de Learn Rust Coding no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Learn Rust Coding, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Learn Rust Coding inclui 4 aulas no total.
O Problema da Ergonomia
Embrulhar um tipo em um newtype aumenta a segurança, mas reduz a praticidade: de repente, é preciso escrever wrapper.0.method() em todos os lugares e reimplementar os métodos manualmente.
O traço Deref pode recuperar grande parte dessa praticidade, permitindo que o invólucro se comporte como o valor que ele contém.
O que Deref Faz
Deref define o que *value produz e dá suporte ao operador .. Quando se chama um método que o invólucro não possui, o compilador tenta novamente no alvo da desreferenciação.
Essa etapa automática é chamada de coerção de desreferenciação.
use std::ops::Deref;
struct MyBox<T>(T);
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &T { &self.0 }
}Coerção de Deref em Ação
Depois que Deref é implementado, chamar métodos internos por meio do invólucro simplesmente funciona. O compilador insere .deref() automaticamente até encontrar o método.
use std::ops::Deref;
struct Name(String);
impl Deref for Name {
type Target = String;
fn deref(&self) -> &String { &self.0 }
}
fn main() {
let n = Name("rustacean".to_string());
println!("len = {}", n.len()); // String::len via deref
}DerefMut para Acesso Mutável
Deref fornece apenas acesso compartilhado. Para chamar, por meio do invólucro, métodos que precisam de &mut self, também implemente DerefMut, que retorna uma referência mutável ao valor interno.
use std::ops::{Deref, DerefMut};
struct Stack(Vec<i32>);
impl Deref for Stack {
type Target = Vec<i32>;
fn deref(&self) -> &Vec<i32> { &self.0 }
}
impl DerefMut for Stack {
fn deref_mut(&mut self) -> &mut Vec<i32> { &mut self.0 }
}Coerção nos Limites das Funções
A coerção de desreferenciação também se aplica aos argumentos. Um &Name sofre coerção para &String, que por sua vez sofre coerção para &str; assim, é possível passar o invólucro diretamente para funções que esperam a referência interna.
fn greet(who: &str) {
println!("hi {}", who);
}
// greet(&name) works: &Name -> &String -> &strUm Exemplo Executável de Coerção
Este programa passa uma referência a um invólucro onde uma fatia de string é esperada. As coerções encadeadas de desreferenciação ocorrem silenciosamente no local da chamada.
use std::ops::Deref;
struct Tag(String);
impl Deref for Tag {
type Target = String;
fn deref(&self) -> &String { &self.0 }
}
fn shout(s: &str) { println!("{}!", s.to_uppercase()); }
fn main() {
let t = Tag("ship".to_string());
shout(&t);
}Não Abuse de Deref
As diretrizes da API do Rust recomendam não implementar Deref para tipos que não sejam ponteiros inteligentes genuínos. O uso excessivo torna imprevisíveis os métodos disponíveis no invólucro e surpreende quem lê o código.
Se o newtype existe para restringir uma API, um Deref abrangente pode expor justamente os métodos que você pretendia ocultar.
AsRef como Alternativa Direcionada
Quando você precisa apenas de uma conversão explícita, em vez de uma coerção automática, implemente AsRef. Quem chama escreve .as_ref() deliberadamente, mantendo clara a interface própria do invólucro.
struct Path(String);
impl AsRef<str> for Path {
fn as_ref(&self) -> &str { &self.0 }
}Encaminhando Métodos Selecionados
Para um invólucro restritivo, prefira escrever manualmente apenas os métodos que deseja expor. Assim, você mantém controle total sobre a API, em vez de expor tudo por meio de Deref.
struct Counter(Vec<u8>);
impl Counter {
fn len(&self) -> usize { self.0.len() }
fn push(&mut self, b: u8) { self.0.push(b); }
}Ponteiros Inteligentes Usam Deref
Ponteiros inteligentes padrão, como Box, Rc e Arc, implementam Deref. É por isso que você pode chamar métodos internos neles de forma transparente. Esse é o uso legítimo e pretendido do traço.
use std::rc::Rc;
fn main() {
let shared = Rc::new(String::from("data"));
// Deref lets us call String methods directly
println!("len = {}", shared.len());
}Escolhendo sua Estratégia de Ergonomia
Escolha com base na intenção. Use Deref para verdadeiros invólucros de ponteiros inteligentes, AsRef para conversões explícitas de referências e encaminhamento manual quando um newtype precisar restringir a API de seu tipo interno.
A escolha errada esconde informações demais ou expõe informações demais.
Verificação Rápida
Decida qual invólucro merece uma implementação de Deref.
Recapitulação
Deref e a coerção de desreferenciação recuperam a praticidade dos invólucros, permitindo que o operador . e os argumentos de referência sejam encaminhados ao valor interno; DerefMut acrescenta acesso mutável.
Reserve Deref para ponteiros inteligentes genuínos. Para newtypes restritivos, use AsRef para conversões explícitas ou encaminhe apenas os métodos que você escolher expor.
Perguntas Frequentes
A aula “Ergonomia de Deref e wrappers” é grátis?
Sim — o texto completo de “Ergonomia de Deref e wrappers” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Learn Rust Coding, atualize para CoddyKit PRO. O curso de Learn Rust Coding inclui 4 aulas no total.
O que vou aprender em “Ergonomia de Deref e wrappers”?
Faça os wrappers parecerem nativos. Você pratica Learn Rust Coding com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Learn Rust Coding?
Nenhuma experiência prévia é necessária. Learn Rust Coding no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Ergonomia de Deref e wrappers”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Learn Rust Coding?
Sim. Cada aula de Learn Rust Coding inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- O padrão Builder
- O padrão Newtype
- Builders com estado de tipo
- Ergonomia de Deref e wrappers