何时使用引用或框来拥有实现结构中特征的字段?

When to use a reference or a box to have a field that implements a trait in a struct?

我有以下代码:

pub trait MyTrait {
    pub fn do_something(&self);
}

如果我想要一个结构 A 有一个字段 a 来实现特征 MyTrait,有 2 个选项:

pub struct A<'a> {
    a: &'a MyTrait
}

pub struct A {
    a: Box<MyTrait>
}

但是在 Difference between pass by reference and by box 上,有人说:

Really, Box<T> is only useful for recursive data structures (so that they can be represented rather than being of infinite size) and for the very occasional performance optimisation on large types (which you shouldn’t try doing without measurements).

除非 A 实现 MyTrait,否则我会说 A 不是递归数据结构,所以这让我觉得我应该更喜欢使用引用而不是框。

如果我有另一个结构 B 引用了某个 A 对象,如下所示:

pub struct A<'a> {
    a: &'a MyTrait
}

pub struct B<'a, 'b: 'a> {
    b: &'a A<'b>
}

我要说 'b'a 大,而且 according to the documentation:

You won't often need this syntax, but it can come up in situations like this one, where you need to refer to something you have a reference to.

我觉得这也是一个糟糕的选择,因为这里的示例非常简单,可能不需要这种高级功能。

那么如何决定我应该使用引用还是框?

不幸的是,您使用的引用适用于完全不同的情况。

Really, Box<T> is only useful for recursive data structures (so that they can be represented rather than being of infinite size) and for the very occasional performance optimisation on large types (which you shouldn’t try doing without measurements).

正在谈论使用 MyEnumBox<MyEnum> 作为数据成员:

  • 它没有与参考文献进行比较,
  • 这不是在谈论特质。

那么...重新动动脑筋,让我们从头再来。


Box 和引用之间的主要区别是 所有权:

  • 一个Box表示周围的struct拥有这条数据,
  • 一个引用表示周围的结构体借用了数据

因此,它们的使用取决于您是想要拥有还是借用,这是一个情境决定:就像螺丝刀和锤子并不比另一个好一样,两者都不比另一个好。

Rc(和Arc)可以在某种程度上减轻决定的需要,因为它们允许多个所有者,但是它们也引入了引用循环的风险,这是调试的噩梦所以我会警告不要过度使用它们。