如何创建一个特征作为返回参数的特征方法?

Aak*_*des 0 rust

我有一个特征B,它定义了一个函数,该函数返回对实现特征的对象的引用A.

enum Error { }

trait A { }

trait B {
    fn create_a<'a>() -> Result<&'a impl A, Error>;
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试编译时,我收到以下错误

error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
  --> src/lib.rs:10:37
   |
10 |     fn create_a<'a>() -> Result<&'a impl A, Error>;
   |                                     ^^^^^^
Run Code Online (Sandbox Code Playgroud)

Jan*_*dec 6

fn create_a<'a>() -> Result<&'a impl A, Error>;

没有任何方法可以创建一个只有任意生命周期的引用,而不具有已经具有该生命周期的对象并且可以作为其所有者 - 并且您根本没有对象,所以这个签名没有任何意义.

为了进一步的论证,我将假设你确实有一个self与生命周期的争论(它可能也需要是可变的):fn create_a<'a>(&'a mut self) -> Result<&'a impl A, Error>;

(注意,因为只有一个生命的时候,所有提及的参考文献有,你的Elid可以吧:fn create_a(&mut self) -> Result<&impl A, Error>;)

现在有两种选择:

  • 您可以将具体类型定义为该特征的成员

    trait B {
        type ImplA: A;
        fn create_a(&mut self) -> Result<&ImplA, Error>;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这不是对象安全的,但它将被静态分派.

    如果需要,您应该能够impl在实现特征时使用类型别名来命名类型.

  • 如果您确实希望B对象安全,请使用对象引用,即

    trait B {
        fn create_a(&mut self) -> Result<&dyn A, Error>;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这种方式调度到返回值总是动态的,但是你这样做是为了允许动态调度到B::create_a最初.