Médio Rust
Struct genérica com método que retorna referência
Enunciado
Crie uma struct genérica Caixa<T> que armazena um valor. Implemente um método obter que retorna uma referência ao valor armazenado. No main, crie uma Caixa com String e outra com i32, e imprima os valores usando obter.
Requisitos
- A struct deve se chamar
Caixae ter um campovalordo tipo genéricoT. - O método
obterdeve retornar&T. - O programa deve imprimir o conteúdo das duas caixas.
Código inicial
struct Caixa<T> {
valor: T,
}
impl<T> Caixa<T> {
// implemente obter
}
fn main() {
// crie caixas e imprima
}
Saída esperada
Caixa de String: Rust
Caixa de i32: 42
Ver dica
O método obter recebe &self e retorna &T. Para imprimir, use println! com {}.
Mostrar solução
struct Caixa<T> {
valor: T,
}
impl<T> Caixa<T> {
// Retorna uma referência ao valor interno
fn obter(&self) -> &T {
&self.valor
}
}
fn main() {
let caixa_string = Caixa { valor: String::from("Rust") };
let caixa_int = Caixa { valor: 42 };
println!("Caixa de String: {}", caixa_string.obter());
println!("Caixa de i32: {}", caixa_int.obter());
}
Passo a passo
- Definimos
struct Caixa<T>com um campovalor: T. O parâmetroTé genérico. - O bloco
impl<T> Caixa<T>implementa métodos para qualquer T. - O método
obter(&self) -> &Tdevolve uma referência ao campovalor. - No
main, criamosCaixa { valor: String::from("Rust") }; o compilador infere T = String. - Criamos
Caixa { valor: 42 }; infere T = i32. - Chamamos
.obter()em cada caixa e imprimimos com{}.
Por que funciona
A struct genérica pode armazenar qualquer tipo. O método obter não precisa de trait bounds porque apenas acessa o campo. A monomorfização gera duas versões da struct e do método: uma para String e outra para i32. Isso mantém a segurança de tipos e evita duplicação de código.
Erros comuns
- Esquecer o
&no retorno:fn obter(&self) -> Ttentaria mover o valor para fora da referência, causando erro. Use&T. - Não importar
String:String::fromestá no prelúdio, então não precisa de import, mas se usarstd::string::Stringexplicitamente, importe. - Tentar imprimir sem
{}:println!(caixa_string.obter())não compila; useprintln!("{}", ...).
Outra forma de resolver
Poderia implementar Deref para acessar o valor diretamente, mas isso expõe o campo e pode não ser desejado. A referência explícita é mais clara.
Saída esperada
Caixa de String: Rust
Caixa de i32: 42