编者注:在实现RFC 599之后,此代码不再生成相同的错误,但答案中讨论的概念仍然有效。
我正在尝试编译这段代码:
trait A {
fn f(&self);
}
struct S {
a: Box<A>,
}
我得到了这个错误:
a.rs:6:13: 6:14 error: explicit lifetime bound required
a.rs:6 a: Box<A>,
我希望S.a
拥有一个A
实例,但我不认为这个生命周期在这里是合适的。我需要做些什么才能让编译器满意呢?
我的Rust版本:
rustc --version
rustc 0.12.0-pre-nightly (79a5448f4 2014-09-13 20:36:02 +0000)
发布于 2014-09-21 21:37:47
这里的问题是,也可以为引用实现一个特征,所以如果你没有为Box指定所需的生命周期,那么任何东西都可能存储在那里。
您可以在此rfc中查看有关生命周期的要求。
因此,一种可能的解决方案是绑定生存期,以便Send
(我们将I放在S中):
trait A {
fn f(&self);
}
struct I;
impl A for I {
fn f(&self) {
println!("A for I")
}
}
struct S {
a: Box<A + Send>
}
fn main() {
let s = S {
a: box I
};
s.a.f();
}
另一种方法是将生存期设置为'a
(我们可以将引用&I或I设置为S):
trait A {
fn f(&self);
}
struct I;
impl A for I {
fn f(&self) {
println!("A for I")
}
}
impl <'a> A for &'a I {
fn f(&self) {
println!("A for &I")
}
}
struct S<'a> {
a: Box<A + 'a>
}
fn main() {
let s = S {
a: box &I
};
s.a.f();
}
注意,这更通用,我们可以同时存储引用和拥有的数据(生命周期为'static
的Send
类型),但是在使用该类型的任何地方都需要一个生命周期参数。
发布于 2014-09-21 21:40:17
(有点老生常谈:A
是一个特征,所以S
并不拥有A
的实例,而是拥有实现A
的某种类型的盒装实例。)
特征对象表示具有某种未知类型的数据,也就是说,关于数据的唯一已知的事情就是它实现了特征A
。由于类型未知,编译器无法直接推断所包含数据的生存期,因此要求此信息在特征对象类型中显式声明。
这是通过Trait+'lifetime
完成的。最简单的方法是只使用'static
,也就是说,完全不允许存储由于作用域而变得无效的数据:
a: Box<A + 'static>
以前(在引入生命周期受限的特征对象的可能性和这个explicit lifetime bound required
错误消息之前),所有装箱的特征对象都是隐式'static
的,也就是说,这种受限形式是惟一的选择。
最灵活的形式是将生命周期暴露在外部:
struct S<'x> {
a: Box<A + 'x>
}
这允许S
存储实现A
的任何类型的特征对象,可能对S
有效的作用域有一些限制(例如,对于'x
小于'static
的类型,S
对象将被捕获在某个堆栈帧中)。
https://stackoverflow.com/questions/25959075
复制相似问题