简体   繁体   中英

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

I have the following code:

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

If I want a struct A to have a field a that implements the trait MyTrait , there are 2 options:

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

or

pub struct A {
    a: Box<MyTrait>
}

But on Difference between pass by reference and by box , someone said:

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).

Unless A implements MyTrait , I'd say A is not a recursive data structure, so that makes me think I should prefer using a reference instead of a box.

If I have another struct B that has a reference to some A object, like this:

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

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

I need to say that 'b is larger than 'a , and 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.

I feel like that's a bad choice too, because the example here is really simple and probably doesn't need this kind of advanced feature.

How to decide whether I should use a reference or a box then?

Unfortunately, the quote you used applied to a completely different situation.

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).

Is speaking about using either of MyEnum or Box<MyEnum> for data members:

  • it is not comparing to references,
  • it is not talking about traits.

So... reset your brain, and let's start from scratch again.


The main difference between Box and a reference is ownership :

  • A Box indicates that the surrounding struct owns the piece of data,
  • A reference indicates that the surrounding struct borrows the piece of data.

Their use, therefore, is dictated by whether you want ownership or borrowing, which is a situational decision: neither is better than the other in the same way that a screwdriver and a hammer are not better than the other.

Rc (and Arc ) can somewhat alleviate the need to decide, as they allow multiple owners, however they also introduce the risk of reference cycles which is its own nightmare to debug so I would caution over overusing them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM