Hands-On Data Structures and Algorithms with Rust
上QQ阅读APP看书,第一时间看更新

Summary

Moving one level above the details of code, this chapter discusses considerations when designing and using types. Rust's differentiation between stack- and heap-allocated variables in code provides a level of control that should be used to improve performance and API flexibility. Sized, a marker trait for mostly stack-allocated values, is the default for generic type parameters and can be relaxed by applying the ?Sized constraint instead.

When working with more object-oriented architectures, trait objects become a way to "work with interfaces" instead of specific implementations. However, they come at a performance cost, that is, dynamic dispatch, another trade-off between maintainability and performance.

Other than moving, Rust can copy or clone variables when necessary. Copy performs a deep copy in the case of sized values; unsized values require a reference that has to be cloned instead. Using these operations is often encountered when working with immutable data types in a principle called copy-on-write. Choosing whether we are able to reason about the object's state at any given time and avoiding data race conditions, but having to create a copy for each change, is another important trade-off when designing data structures.

This trade-off will become apparent in the next chapter, where we will start working with lists, such as the singly-linked list, doubly-linked list, and the dynamic array.