1

编者注:问题中提供的代码在 Rust 1.0 中按原样编译。

我试过了:

trait Inner {}

struct Outer<'a> {
    inner: &'a Inner,
}

但编译器抱怨:

   Compiling tst v0.1.0 (file:///home/chris/rust/tst)
/home/chris/rust/tst/src/main.rs:4:14: 4:19 error: explicit lifetime bound required
/home/chris/rust/tst/src/main.rs:4   inner: &'a Inner,
4

2 回答 2

6

我如何告诉 Rust 我想要一个包含对实现特征的东西的引用的结构?

有两种方法。首先,首选的是使用泛型:

struct Outer<'a, T> {
    inner: &'a T,
}

impl<'a, T: Inner> Outer<'a, T> {
    // ...
}

此方法是最有效的,因为所有函数调用都是静态分派的。它也是最安全的一种,但它的缺点是您必须在使用的任何地方指定特征绑定,Outer<T>并且您将无法Inner在不同时间在同一结构中保存不同的实现,因为T必须提前知道.

另一种方法是使用 trait 对象:

struct Outer<'a> {
    inner: &'a (Inner + 'a),
}

这是您已经尝试过的,您看到的错误是由于未指定生命周期限制引起的:那个+ 'a东西。您需要指定生命周期限制,因为可以为具有生命周期参数(如Outer)的结构实现特征,并且如果您将这样的结构装箱到特征对象中,则需要一种在特征对象类型中指定其生命周期参数的方法。

trait 对象的优点是注释数量更少,并且能够使用任意类型作为inner具有相同Outer值的字段,只要它满足Inner绑定。缺点是您将获得动态调度,这可能会稍微降低效率。如果没有额外的机器,您也无法取回 trait 对象的原始类型。

于 2014-10-14T15:48:42.363 回答
-1

这是一个使用生命周期说明符的结构示例。

我必须创建一个结构体,其字段是对 type 的引用SWide。这个字段需要是结构内部的引用,所以我在结构中添加了一个生命周期说明符,并且还在 impl 中添加了一个生命周期说明符,请注意您必须在 impl 行中两次使用相同的生命周期说明符:

extern crate mysql;

use mysql::Pool;
use swide::SWide;

pub struct Context<'a> {
    pub connection_pool: Pool,
    pub cache: Option<&'a SWide>,
}
impl<'a> Context<'a> {
    pub fn new_with_cache(connection_pool: Pool, cache: Option<&'a SWide>) -> Self {
        Context {
            connection_pool: connection_pool,
            cache: cache,
        }
    }
}
于 2018-03-13T02:19:49.837 回答