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 Fooescolhe o tipo concreto que retorna, sem escrevê-lo na fonte. Uma função que retorna um tipo genérico comocollect<B>() -> Bpode 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.