In this lesson, you will learn how to design flexible resource containers that can toggle between owning their data and borrowing it, depending on the needs of your application.
The Problem of Rigid Ownership
Often, a container might need to hold data that exists elsewhere, or it might need to "take charge" of that data entirely. If you hard-code a struct to always own its contents (e.g., struct Box<T> { data: T }), you lose the ability to use that same container to point to a temporary memory buffer or a static resource.
Using Generics for Strategy
We can use Rust's powerful type system—specifically generics—to allow a container to decide its "storage strategy" at compile time. By defining a container that holds either an owned value or a reference, we create a reusable tool that adapts to the caller’s requirements.
Consider a simple Resource container:
enum Resource<'a, T> {
Owned(T),
Borrowed(&'a T),
}
impl<'a, T> Resource<'a, T> {
fn get(&self) -> &T {
match self {
Resource::Owned(ref val) => val,
Resource::Borrowed(val) => val,
}
}
}
Why This Matters
By using this pattern, your Resource container becomes incredibly versatile. If you are reading data from a memory-mapped file (where you shouldn't own the data), you can use the Borrowed variant. If you are generating a value dynamically at runtime, you can use the Owned variant.
Because Rust enforces lifetimes, the compiler ensures that your Borrowed variant never outlives the data it points to. Meanwhile, the Owned variant provides the stability needed for data that must persist as long as the container does. By designing your containers this way, you avoid duplicating data unnecessarily while maintaining the strict memory safety guarantees that define Rust. You aren't just storing values; you are encoding the relationship between the container and the data it holds.
Key Takeaway: By using enums or generics to represent either owned or borrowed data, you create highly reusable containers that minimize memory overhead while remaining strictly compatible with Rust's borrow checker.