问题
Rust provides a few ways to store a collection of elements inside a user-defined struct. The struct can be given a custom lifetime specifier, and a reference to a slice:
struct Foo<'a> {
elements: &'a [i32]
}
impl<'a> Foo<'a> {
fn new(elements: &'a [i32]) -> Foo<'a> {
Foo { elements: elements }
}
}
Or it can be given a Vec
object:
struct Bar {
elements: Vec<i32>
}
impl Bar {
fn new(elements: Vec<i32>) -> Bar {
Bar { elements: elements }
}
}
What are the major differences between these two approaches?
- Will using a
Vec
force the language to copy memory whenever I callBar::new(vec![1, 2, 3, 4, 5])
? - Will the contents of
Vec
be implicitly destroyed when the ownerBar
goes out of scope? - Are there any dangers associated with passing a slice in by reference if it's used outside of the struct that it's being passed to?
回答1:
A Vec
is composed of three parts:
- A pointer to a chunk of memory
- A count of how much memory is allocated (the capacity)
- A count of how many items are stored (the size)
A slice is composed of two parts:
- A pointer to a chunk of memory
- A count of how many items are stored (the size)
Whenever you move either of these, those fields are all that will be copied. As you might guess, that's pretty lightweight. The actual chunk of memory on the heap will not be copied or moved.
A Vec
indicates ownership of the memory, and a slice indicates a borrow of memory. A Vec
needs to deallocate all the items and the chunk of memory when it is itself deallocated (dropped in Rust-speak). This happens when it goes out of scope. The slice does nothing when it is dropped.
There are no dangers of using slices, as that is what Rust lifetimes handle. These make sure that you never use a reference after it would be invalidated.
来源:https://stackoverflow.com/questions/32571441/what-is-the-difference-between-storing-a-vec-vs-a-slice