我有一个特征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>;
| ^^^^^^
答案 0 :(得分:6)
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>;
}
这种向返回值进行分配的方式始终是动态的,但是您要这样做是为了始终允许动态对B::create_a
进行分配。
答案 1 :(得分:-1)
有多种返回特征的方法,它们都依赖某种间接性。
Box<A>
Rc<A>
/ Arc<A>
&dyn A
T
1、2、3和4之差为static vs dynamic dispatching。