impl trait参数和泛型函数参数之间有什么区别?

Fre*_*ios 11 rust

impl Traits可以用作函数参数.这个和具有特征约束的泛型函数之间是否存在差异?

trait Foo {}

fn func1(_: impl Foo) {}

fn func2<T: Foo>(_: T) {}
Run Code Online (Sandbox Code Playgroud)

int*_*jay 11

impl Traits作为函数参数被设计为匿名泛型参数.请参阅RFC,其中说:

展开impl Trait以允许在参数中使用,其行为类似于匿名通用参数.

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
Run Code Online (Sandbox Code Playgroud)

但是,一个区别是impl Trait参数不能明确指定其类型:

fn foo<T: Trait>(t: T)
fn bar(t: impl Trait)

foo::<u32>(0) // this is allowed
bar::<u32>(0) // this is not
Run Code Online (Sandbox Code Playgroud)

扩展到参数位置部分的动机解释了为什么为现有特征添加了附加语法.简而言之,它具有与impl函数返回位置中的特征类似的语法,这提高了可学习性,并改善了人体工程学.


lje*_*drz 5

两者至少在以下简单测试用例中产生相同的组装:

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);
}
Run Code Online (Sandbox Code Playgroud)