简体   繁体   English

为什么Box的“明确的生命周期约束” <T> 指导?

[英]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.

相关问题 Rust函数返回一个闭包:``需要显式生命周期绑定“ - Rust function returning a closure: ``explicit lifetime bound required" 为什么这个 Rust 代码编译时在结构上有生命周期绑定,但如果绑定仅在 impl 上,则会给出生命周期错误? - Why does this Rust code compile with a lifetime bound on the struct, but give a lifetime error if the bound is only on the impl? 为什么这个生命周期限制不会导致错误? - Why doesn't this lifetime bound cause an error? T 形式的生命周期界限:'a - Lifetime bound of the form T: 'a 我应该在哪里添加明确的生命周期限制? - where should I add an explicit lifetime bound? 在impl块上不需要在通用参数上绑定生命周期 - Lifetime bound on generic parameter not required on impl block 在 Rust 中,当对作为通用参数传递的值进行装箱时,为什么需要“静态”生命周期限制? - In Rust, when boxing a value passed as a generic argument, why is a `'static` lifetime bound required? 具有特征的类型定义:指定显式生命周期界限的差异? - Type definition with a trait: Differences of specifying an explicit lifetime bound? 如何将明确的生命周期应用于返回的特征? - How do I apply an explicit lifetime bound to a returned trait? 如何为关联常量在 Self 上设置显式生命周期? - How to put explicit lifetime bound on Self for associated constant?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM