impl Trait
s can be used as function arguments. Are there differences between this and a generic function with a trait constraint?
trait Foo {}
fn func1(_: impl Foo) {}
fn func2<T: Foo>(_: T) {}
impl Trait
s as function arguments are desugared to an anonymous generic parameter. See the RFC, which says:
Expand
impl Trait
to allow use in arguments, where it behaves like an anonymous generic parameter.
There's also an example in the RFC:
// These two are equivalent
fn map<U>(self, f: impl FnOnce(T) -> U) -> Option<U>
fn map<U, F>(self, f: F) -> Option<U> where F: FnOnce(T) -> U
However, one difference is that impl Trait
arguments cannot have their types explicitly specified:
fn foo<T: Trait>(t: T)
fn bar(t: impl Trait)
foo::<u32>(0) // this is allowed
bar::<u32>(0) // this is not
The Motivation for expanding to argument position section explains why additional syntax was added for an existing feature. In short, it's for having similar syntax as impl
traits in function return position, which improves learnability, and to improve ergonomics.
Both produce identical assembly, at least with the following simple test case:
trait Foo {}
struct Bar;
impl Foo for Bar {}
fn func1(_: impl Foo) {}
fn func2<T: Foo>(_: T) {}
fn main() {
let x = Bar;
let y = func1(x); // or func2(x);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With