impl Trait
Semelhante aos limites de trait, a sintaxe do trait impl
pode ser usada em argumentos de funções e em valores de retorno:
// Código simplificado para: // fn add_42_millions<T: Into<i32>>(x: T) -> i32 { fn add_42_millions(x: impl Into<i32>) -> i32 { x.into() + 42_000_000 } fn pair_of(x: u32) -> impl std::fmt::Debug { (x + 1, x - 1) } fn main() { let many = add_42_millions(42_i8); println!("{many}"); let many_more = add_42_millions(10_000_000); println!("{many_more}"); let debuggable = pair_of(27); println!("debuggable: {debuggable:?}"); }
O impl Trait
permite que você trabalhe com tipos que você não pode nomear. O significado de impl Trait
é um pouco diferente nas diferentes posições.
-
Como parâmetro, o trait
impl
é como um parâmetro genérico anônimo com um limitador de características (trait). -
Como tipo de retorno, significa que o tipo de retorno é algum tipo concreto que implementa o trait, sem nomear o tipo. Isso pode ser útil quando você não deseja expor o tipo concreto em uma API pública.
A inferência é difícil na posição de retorno. Uma função que retorna
impl Foo
escolhe o tipo concreto que retorna, sem escrevê-lo na fonte. Uma função que retorna um tipo genérico comocollect<B>() -> B
pode retornar qualquer tipo que satisfaçaB
, e o chamador pode precisar escolher um, como comlet x: Vec<_> = foo.collect()
ou com o turbofish,foo.collect::<Vec<_>>()
.
Qual é o tipo de debuggable
? Tente let debuggable: () = ..
para ver o que a mensagem de erro mostra.