[英]Why “explicit lifetime bound required” for Box<T> in struct?
Editor's note: This code no longer produces the same error after RFC 599 was implemented, but the concepts discussed in the answers are still valid.
编者注:实施RFC 599后,此代码不再产生相同的错误,但答案中讨论的概念仍然有效。
I'm trying to compile this code: 我正在尝试编译此代码:
trait A {
fn f(&self);
}
struct S {
a: Box<A>,
}
and I'm getting this error: 我收到这个错误:
a.rs:6:13: 6:14 error: explicit lifetime bound required
a.rs:6 a: Box<A>,
I want Sa
to own an instance of A
, and don't see how that lifetime is appropriate here. 我希望
Sa
拥有一个A
的实例,并且不知道这个生命周期是如何合适的。 What do I need to do to make the compiler happy? 我需要做些什么才能使编译器满意?
My Rust version: 我的Rust版本:
rustc --version
rustc 0.12.0-pre-nightly (79a5448f4 2014-09-13 20:36:02 +0000)
(Slightly pedantic point: that A
is a trait, so S
is not owning an instance of A
, it is owning an boxed instance of some type that implements A
.) (稍微迂腐一点:
A
是一个特征,所以S
不拥有A
的实例 ,它拥有一个实现A
的某种类型的盒装实例。)
A trait object represents data with some unknown type, that is, the only thing known about the data is that it implements the trait A
. 特征对象表示具有某种未知类型的数据,也就是说,唯一已知的数据是它实现了特征
A
Because the type is not known, the compiler cannot directly reason about the lifetime of the contained data, and so requires that this information is explicitly stated in the trait object type. 由于类型未知,编译器无法直接推断所包含数据的生命周期,因此需要在特征对象类型中明确说明此信息。
This is done via Trait+'lifetime
. 这是通过
Trait+'lifetime
。 The easiest route is to just use 'static
, that is, completely disallow storing data that can become invalid due to scopes: 最简单的方法是使用
'static
,即完全禁止存储因范围而变得无效的数据:
a: Box<A + 'static>
Previously, (before the possibility of lifetime-bounded trait objects and this explicit lifetime bound required
error message was introduced) all boxed trait objects were implicitly 'static
, that is, this restricted form was the only choice. 以前,(在生命周期限制的特征对象的可能性和这个
explicit lifetime bound required
错误消息被引入之前)所有盒装的特征对象都是隐式的'static
,也就是说,这种限制形式是唯一的选择。
The most flexible form is exposing the lifetime externally: 最灵活的形式是在外部暴露生命:
struct S<'x> {
a: Box<A + 'x>
}
This allows S
to store a trait object of any type that implements A
, possibly with some restrictions on the scopes in which the S
is valid (ie for types for which 'x
is less than 'static
the S
object will be trapped within some stack frame). 这允许
S
存储实现A
的任何类型的特征对象,可能对S
有效的范围有一些限制(即对于'x
小于'static
的类型, S
对象将被捕获在某个堆栈中帧)。
The problem here is that a trait can be implemented for references too, so if you don't specify the required lifetime for Box anything could be stored in there. 这里的问题是也可以为引用实现一个特性,所以如果你没有为Box指定所需的生命周期,那么任何东西都可以存储在那里。
You can see about lifetime requirements in this rfc . 您可以在此rfc中查看有关生命周期的要求。
So one possible solution is to bind the lifetime so Send
(we put I in S): 所以一个可能的解决方案就是绑定生命周期所以
Send
(我把我放在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();
}
The other is setting the lifetime to 'a
(we can put a reference &I or I to S): 另一种是将生命周期设置为
'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();
}
Note that this is more general and we can store both references and owned data ( Send
kind that has a lifetime of 'static
) but you require a lifetime parameter everywhere the type is used. 请注意,这是更通用的,我们可以存储引用和拥有数据(具有生命周期
'static
Send
类型),但是在使用类型的任何地方都需要生命周期参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.