6 ms·
I read somewhere that immutable and mutable borrows are perhaps alternatively understood as exclusive and shared borrows. This means, if you have a &mut then y
by _nalply 7y ago
I read somewhere that immutable and mutable borrows are perhaps alternatively understood as exclusive and shared borrows.
This means, if you have a &mut then you have an exclusive borrow. No other borrows are possible as long as your &mut lives (i. e. did not yet go out of scope). Usually this exclusive borrow is used for mutating values.
This dichotomy in terminology is shown when you learn about interior mutability. Here you can mutate values without having an exclusive borrow, an example is RefCell. The price you pay for this convenience is run-time checking of access. RefCell disallows mutation if some other location in your code already has asked for mutable access.
- cube2222 7y agoI suppose you can think about it as having a shared borrow to the ref cell, but using it to gain an exclusive borrow to the data underneath, to fit the intuition.
- danieldk 7y agoI read somewhere that immutable and mutable borrows are perhaps alternatively understood as exclusive and shared borrows. Yes, when it comes to exterior mutability, it's basically single mutable xor multiple immutable. The price you pay for this convenience is run-time checking of access. The nice thing is that RefCell is not magic, it's Rust all the way down. E.g. the status of the borrow is updated by the destructors (Drop) of the reference types. All administration is done using a signed integer to do reference counting. The value 0 means 'no borrows', any positive number indicates the number of immutable borrows, -1 means one mutable borrow. It's well worth reading the implementation of RefCell some time!
- jrvidal 7y ago> The nice thing is that RefCell is not magic I'd like to point out that `RefCell` does contain a bit of magic, since it is based on `UnsafeCell`, which is _the_ core "primitive" of Rust that enables interior mutability: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html (Not trying to be pedantic, just to clarify things for less knowledgeable readers).
- simias 7y agoI assume the parent meant that there was no compiler magic at play, as far as I know UnsafeCell is written in pure Rust, just using unsafe code: https://doc.rust-lang.org/src/core/cell.rs.html#1486-1488 https://doc.rust-lang.org/src/core/cell.rs.html#1486-1488 So basically if Rust's stdlib didn't provide it, you could reimplement it yourself from scratch. EDIT: actually, reading the comments, it looks like I'm wrong about that: > If you have a reference `&SomeStruct`, then normally in Rust all fields of `SomeStruct` are immutable. The compiler makes optimizations based on the knowledge that `&T` is not mutably aliased or mutated, and that `&mut T` is unique. `UnsafeCell<T>` is the only core language feature to work around the restriction that `&T` may not be mutated.
- jrvidal 7y agoI'm not sure that's correct. `UnsafeCell` is a Rust lang item that might disable some optimizations, I think? https://doc.rust-lang.org/src/core/cell.rs.html#1483 https://doc.rust-lang.org/src/core/cell.rs.html#1483
- simias 7y agoYou're right, I just saw that. Well I least I learned something new about Rust today!
- aratakareigen 7y agoYep, you can't implement UnsafeCell yourself without running into undefined behavior.
- Sean1708 7y agoWRT your edit: #[lang = "unsafe_cell"] This tells you that UnsafeCell is a Language Item[1], which basically means that the compiler does have knowledge of it. [1]: https://doc.rust-lang.org/beta/unstable-book/language-features/lang-items.html https://doc.rust-lang.org/beta/unstable-book/language-featur...
- 7y ago
- Waterluvian 7y agoThis line in the Rust book is what made it click for me: "Rust can figure out definitively whether the method is reading (&self), mutating (&mut self), or consuming (self)." This was from the methods chapter but I think it applies globally. You either borrow to read, borrow to mutate, or consume (and possibly return a different value back) I'm sure there will be more nuance but I think this is a good conceptual foundation to begin with.
- jakeec 7y agoWhat does 'consume' mean in this context?
- Waterluvian 7y agoThe function "consumes" the value. Its no longer valid in the function caller's scope. Often the purpose is to consume the value and return a new kind of value. Maybe `validate_square` takes in `Shape` and returns `Option<Shape>` If valid or invalid, we have consumed the shape so it cant be reused by accident and can't be used without handling the optional branches. I'm new so maybe I'm off on this.
- Cyph0n 7y agoIn Rust, this is how “ownership” works. Once a variable is moved to a new scope, ownership moves with it, which means that it cannot be used in the current scope anymore.
- dthul 7y ago"Consume" is comparable to a "move" in C++.
- ChrisSD 7y agoIf I consume your apple then you no longer have your apple and the apple will be gone once I finish with it. But because I eat apples whole, I can spit it out before I swallow and return it to you. The analogy may not be perfect but the point is complete control of the object has been transferred to the function and so you no longer have access to it and it will be destroyed once the function ends, unless it's returned.
- tomtomtom777 7y agoWell said. Rust's terminology is kind of reversed: It is stated that a mutable reference cannot be shared, while in fact a reference is called "mutable" when it cannot be shared. The terminology is understandable and great to get started, but once you dive in deeper into atomics and internal mutability, it's rather crucial to understand this reversal.
- int_19h 7y agoYou might find this interesting. It's about C++, but it's a very similar take: https://channel9.msdn.com/posts/C-and-Beyond-2012-Herb-Sutter-You-dont-know-blank-and-blank https://channel9.msdn.com/posts/C-and-Beyond-2012-Herb-Sutte...