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

States and reasoning

The state of an object is essentially the current values that its fields have at any given time. Changing this state is done by the object itself via messages on defined behavior (called methods) according to object-orientation principles. These state changes require mutability.

Throughout their lifetimes, most objects change their states multiple times, and since this happens at runtime, we find ourselves often looking at an object's debug print in frustration, thinking, "How did this value get here?"

Immutable data structures remedy this by making it impossible to change their contents, so any time you would look at an object, it has exactly the right values. It's a known fact that the majority of variables don't need to be mutable, and unless there is a resource constraint, creating another instance of the object with its new state is recommended. This principle, called copy-on-write, improves readability for better maintenance.

A popular type that employs copy-on-write is the String—in almost any language. The type wraps a byte array and interprets it using a provided character set (usually UTF-8), and if you modify a character, this array is copied and saved with the changes made. This is done so often that String allocations are a common performance pitfall.

In the Rust standard library, there is a Cow enumeration ( std::borrow::Cow) that lazily clones a contained reference whenever mutation or ownership is requested. For a great example, check out the Cow documentation: https://doc.rust-lang.org/std/borrow/enum.Cow.html.

The principle of copy-on-write can also be found in filesystems to create snapshots (for example, in ZFS or BRTFS) and provides the benefits of both immutability and mutability at the cost of runtime resources. It's a trade-off between maintainability and absolute performance. A similar concept is employed by persistent data structures, which can be partially or fully persistent and still be immutable.