Trait impl
Semelhante aos limites do trait, a sintaxe do trait impl
pode ser usada em argumentos de funções e em valores de retorno:
use std::fmt::Display; fn get_x(name: impl Display) -> impl Display { format!("Olá {name}") } fn main() { let x = get_x("foo"); println!("{x}"); }
impl Trait
permite que você trabalhe com tipos que você não pode nomear.
O significado do trait impl
é um pouco difere de acordo com sua posição.
-
For a parameter,
impl Trait
is like an anonymous generic parameter with a trait bound. -
For a return type, it means that the return type is some concrete type that implements the trait, without naming the type. This can be useful when you don’t want to expose the concrete type in a public API.
Inference is hard in return position. A function returning
impl Foo
picks the concrete type it returns, without writing it out in the source. A function returning a generic type likecollect<B>() -> B
can return any type satisfyingB
, and the caller may need to choose one, such as withlet x: Vec<_> = foo.collect()
or with the turbofish,foo.collect::<Vec<_>>()
.
Este exemplo é ótimo, porque usa impl Display
duas vezes. Isso ajuda a explicar que nada impõe que, nos dois usos, impl Display
seja do mesmo tipo. Se usássemos um único T: Display
, imporia a restrição de que o tipo T
de entrada e o tipo T
de retorno são do mesmo tipo. Isso não funcionaria para esta função específica, pois o tipo que esperamos como entrada provavelmente não é o que format!
retorna. Se quiséssemos fazer o mesmo através da sintaxe : Display
, precisaríamos de dois parâmetros genéricos independentes.