Eug*_*sov 21 rust rust-obsolete
编者注:实施RFC 599后,此代码不再产生相同的错误,但答案中讨论的概念仍然有效.
我正在尝试编译此代码:
trait A {
fn f(&self);
}
struct S {
a: Box<A>,
}
Run Code Online (Sandbox Code Playgroud)
我收到这个错误:
a.rs:6:13: 6:14 error: explicit lifetime bound required
a.rs:6 a: Box<A>,
Run Code Online (Sandbox Code Playgroud)
我想S.a拥有一个实例A,并且不知道这个生命周期是如何合适的.我需要做些什么才能使编译器满意?
我的Rust版本:
rustc --version
rustc 0.12.0-pre-nightly (79a5448f4 2014-09-13 20:36:02 +0000)
Run Code Online (Sandbox Code Playgroud)
huo*_*uon 21
(稍微迂腐一点:这A是一个特性,所以S不拥有一个实例A,它拥有一个实现的某种类型A的盒装实例.)
特征对象表示具有某种未知类型的数据,也就是说,唯一已知的数据是它实现了特征A.由于类型未知,编译器无法直接推断所包含数据的生命周期,因此需要在特征对象类型中明确说明此信息.
这是通过Trait+'lifetime.最简单的方法是使用'static,即完全禁止存储因范围而变得无效的数据:
a: Box<A + 'static>
Run Code Online (Sandbox Code Playgroud)
以前,(在explicit lifetime bound required引入生命周期特征对象的可能性和引入此错误消息之前)所有盒装特征对象都是隐式的'static,也就是说,这种限制形式是唯一的选择.
最灵活的形式是在外部暴露生命:
struct S<'x> {
a: Box<A + 'x>
}
Run Code Online (Sandbox Code Playgroud)
这允许S存储实现的任何类型的特征对象A,可能对其S有效的范围有一些限制(即,对于'x小于'static该S对象的类型将被捕获在某个堆栈帧内).
Arj*_*jan 18
这里的问题是也可以为引用实现一个特性,所以如果你没有为Box指定所需的生命周期,那么任何东西都可以存储在那里.
您可以在此rfc中查看有关生命周期的要求.
因此,一种可能的解决方案是绑定生命周期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();
}
Run Code Online (Sandbox Code Playgroud)
另一种是将生命周期设置为'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();
}
Run Code Online (Sandbox Code Playgroud)
请注意,这是更通用的,我们可以存储引用和拥有的数据(Send具有生命周期的类型'static),但是在使用类型的任何地方都需要生命周期参数.
| 归档时间: |
|
| 查看次数: |
7673 次 |
| 最近记录: |