我有一个特征 B
,它定义了一个函数,该函数返回对实现特征 A
的对象的引用。
enum Error { }
trait A { }
trait B {
fn create_a<'a>() -> Result<&'a impl A, Error>;
}
但是,当我尝试 compile我收到以下错误
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>;
| ^^^^^^
最佳答案
fn create_a<'a>() -> Result<&'a impl A, Error>;
如果没有一个已经拥有该生命周期并且可以充当其所有者的对象,就无法创建一个与任意生命周期一样长的引用——而且这里根本没有任何对象,所以这个签名毫无意义.
为了进一步论证,我假设你确实有一个 self
与那个生命周期的争论(它可能也需要可变):fn create_a<'a>(&'a mut self) -> Result<&'a impl A, Error>;
(请注意,由于所有提到的引用只有一个生命周期,您可以将其省略:fn create_a(&mut self) -> Result<&impl A, Error>;
)
现在有两个选择:
您可以将具体类型定义为该特征的成员,例如
trait B { type ImplA: A; fn create_a(&mut self) -> Result<&ImplA, Error>; }
这不是对象安全的,但它会被静态调度。
您应该能够使用
impl
实现特征时的类型别名以根据需要命名类型。如果你想要
B
要对象安全,请使用对象引用,即trait B { fn create_a(&mut self) -> Result<&dyn A, Error>; }
这种对返回值的分派(dispatch)总是动态的,但是你这样做是为了允许动态分派(dispatch)到
B::create_a
无论如何首先。
关于rust - 如何创建一个以特征作为返回参数的特征方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53164725/