Being a novice C++ programmer learning Rust, I am not fully comfortable with ownership and how the borrow checker works, so while experimenting with it, I've come to an analogy that I wanted to inquire about. Could I think of rusts' transfer of ownership as the compiler inserting a free immediately after any function call that borrows any heap-allocated value, as an example:
analogy(Type* val) {
...
}
function() {
Type* arg = new Type()
analogy(arg)
// Could I think of the borrow checker on assumption
// as a preprocessor that inserts the following
delete arg
// After doing so, a static analyzer is run by the compiler
// which can trivially detect an error such as this
print(arg)
}
Actually, there is already an analogy in the standard library: instead of compile-time borrow-checking, you can use run-time borrow-checking with RefCell (single-threaded) or RwLock (multi-threaded).
We can thus convert an example by using RefCell, try it on the playground:
use std::cell::RefCell;
pub fn original() {
let mut x = String::from("Hello, world!");
let y = &x;
// x.push('!'); // Borrow-checking error.
println!("{y:?}");
x.push('!');
println!("{x:?}");
}
pub fn converted() {
let x = RefCell::new(String::from("Hello, world!"));
let y = x.borrow();
// x.borrow_mut().push('!'); // Panic.
println!("{y:?}");
x.borrow_mut().push('!');
println!("{x:?}");
}
Hence, rather than a temporary "delete", it's best to think of borrowing as read-write locking:
&T locks for reads, and multiple readers are allowed, but no writer is.&mut T locks for writes, no other reader nor writer is allowed.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With