impl trait 参数和泛型函数参数之间有什么区别?
impl Trait
s 可以用作函数参数.这与具有 trait 约束的泛型函数有区别吗?
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 作为函数参数被脱糖为匿名泛型参数.参见 RFC,其中说:
impl Trait
s as function arguments are desugared to an anonymous generic parameter. See the RFC, which says:
扩展 impl Trait
以允许在参数中使用,它的行为类似于匿名泛型参数.
Expand
impl Trait
to allow use in arguments, where it behaves like an anonymous generic parameter.
RFC 中还有一个例子:
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
然而,一个区别是 impl Trait
参数不能明确指定它们的类型:
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
扩展到参数位置的动机 部分解释了为什么要为现有功能添加额外的语法.简而言之,它是为了在函数返回位置具有与 impl
特征相似的语法,从而提高可学习性,并改善人体工程学.
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.