iTranslated by AI
Introduction to Rust Ownership
Introduction
Just as you must close a file after opening it, you must free memory after you use it. This is because it is more economical to reuse it.
There are various ways to manage memory. Some languages, like C++, require manual management, while others, like Python, run a dedicated program[1]. The former approach is cumbersome and error-prone, while the latter incurs overhead and lacks controllability.
Rust manages memory through a mechanism called ownership. This article aims to provide an intuitive understanding of ownership. For a precise explanation, please refer to The book.
Ownership
There can be multiple variables associated with a single memory region. Among these, exactly one variable is responsible for freeing the memory. This is called ownership. Since memory should be freed exactly once, there is only one owner. Variables that are not owners are simply called references.
Freeing Memory
Memory is automatically freed when a variable goes out of scope[2]. This is because variables cannot be accessed from outside the scope. The actual operation is defined by the Drop trait, where drop() is executed when a variable leaves its scope.
For user-defined types, drop() is called recursively on the fields, so you will rarely need to implement it manually. You only need to implement the Drop trait if you want to perform some processing before dropping the fields or if you are using raw pointers.
Transfer of Ownership
Ownership is transferred (moved) through assignment operations, move, and return. This allows avoiding unnecessary copies[3] and coexists with mechanisms like functions and closures.
let data = {
let mut vec = Vec::new();
/* Calculation using many variables */
vec // Transfer ownership. Other memory used for calculation will be freed.
};
let renamed = data; // Transfer ownership. Avoids clone.
let f = move || { // Transfer ownership to the closure
println!("{:?}", renamed)
};
Using Scopes
By leveraging scopes, you can free unnecessary memory and move required information. You can do the same with working memory. Furthermore, you can visually associate variables with processes. By utilizing scopes, you can write human-friendly code with excellent readability and maintainability.
Conclusion
This article provided an intuitive explanation of ownership in Rust. Since ownership is managed by the compiler, there is no runtime overhead. It can be said that this mechanism brings together the best of both manual and automatic memory management.
At the beginning, I stated that "just as you must close a file after opening it, you must free memory after you use it." In Rust, the Drop trait is utilized to automatically close files when a file object goes out of scope. Such cleanup processes are also a byproduct of ownership.
-
The latter mechanism is called Garbage Collection (GC). ↩︎
-
In reality, it is a bit more complex. For details, refer to the reference. ↩︎
-
Copytypes simply duplicate data instead of transferring ownership. In Rust, explicit copies are referred to asClone, while implicit copies are referred to asCopy, distinguishing the two. ↩︎
Discussion