我有一个特征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)
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最初.