代码之家  ›  专栏  ›  技术社区  ›  Boiethios

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

  •  33
  • Boiethios  · 技术社区  · 6 年前

    impl Trait s can be used as function arguments . 这和具有特征约束的泛型函数之间有什么区别吗?

    trait Foo {}
    
    fn func1(_: impl Foo) {}
    
    fn func2<T: Foo>(_: T) {}
    
    2 回复  |  直到 5 年前
        1
  •  27
  •   Shepmaster Lukas Kalbertodt    5 年前

    impl Trait s作为函数参数被分解为匿名泛型参数。请参阅 RFC ,表示:

    扩大 impl特征 允许在参数中使用,其行为类似于匿名泛型参数。

    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特征 参数不能显式指定其类型:

    fn foo<T: Trait>(t: T)
    fn bar(t: impl Trait)
    
    foo::<u32>(0) // this is allowed
    bar::<u32>(0) // this is not
    

    这个 Motivation for expanding to argument position 第节解释了为现有功能添加其他语法的原因。简而言之,它的语法与 impl 功能返回位置的特征,这提高了可学习性,并改善了人机工程学。

        2
  •  8
  •   Shepmaster Lukas Kalbertodt    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);
    }