Traits Genéricos
Traits também podem ser genéricos, assim como tipos e funções. Os parâmetros de um trait recebem tipos concretos quando ele é usado.
#[derive(Debug)]
struct Foo(String);
impl From<u32> for Foo {
fn from(from: u32) -> Foo {
Foo(format!("Convertido de inteiro: {from}"))
}
}
impl From<bool> for Foo {
fn from(from: bool) -> Foo {
Foo(format!("Convertido de booleano: {from}"))
}
}
fn main() {
let from_int = Foo::from(123);
let from_bool = Foo::from(true);
println!("{from_int:?}, {from_bool:?}");
}
-
O trait
Fromserá abordado mais tarde no curso, mas sua definição na documentaçãostdé simples. -
As implementações do trait não precisam cobrir todos os possíveis parâmetros de tipo. Aqui,
Foo::from("hello")não seria compilado porque não há implementaçãoFrom<&str>paraFoo. -
Os traits genéricos recebem tipos como “entrada”, enquanto os tipos associados são uma espécie de tipo de “saída”. Um trait pode ter várias implementações para diferentes tipos de entrada.
-
Na verdade, o Rust exige que no máximo uma implementação de um trait corresponda a qualquer tipo T. Ao contrário de algumas outras linguagens, o Rust não tem uma heurística para escolher a correspondência “mais específica”. Há trabalho em adicionar esse suporte, chamado especialização.