0

I'm writing some simulation code with a vector of entities. Each entity must be updated with read access to the other entities. There are different types of entities, and each type can have one or more states.

Is there a way in Rust to get both a mutable reference to a single element, and an immutable reference to the vector of other elements? Right now I'm using a combination of a mutable reference to the vector and an index into it.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
SongWithoutWords
  • 471
  • 5
  • 12
  • *an immutable reference to the [...] other elements* — this doesn't make sense because there can be items **before** and **after** a given element. This would require two additional references, at a minimum. – Shepmaster Feb 03 '19 at 03:10
  • @Shepmaster, I'm not sure you understand. In C++ you can have a `Vector` that is mutable (non const). You could pass this `Vector`, along with a mutable reference to one of its elements, to a function with a signature like `void UpdateElement(const Vector& elems, T& elem)`. This is what I am asking about, can update the question. – SongWithoutWords Feb 03 '19 at 03:12
  • 1
    [The duplicate applied to your question](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=29e738aeb9eddea55593483820b5eb8a) – Shepmaster Feb 03 '19 at 03:17
  • @SongWithoutWords In your example of C++ code, you have one mutable reference and one const reference to the same memory, that is unsafe in rust. – Stargateur Feb 03 '19 at 03:18
  • Sure, but in C++ you can also trigger undefined behavior quite easily. Rust doesn't allow that. If something is immutable; it's **immutable** (in the absence of interior mutability). IIRC, C++ also allows you to cast away the `const`-ness of a value. – Shepmaster Feb 03 '19 at 03:18
  • Yes - I understand that the borrow checker does not allow this by default. Conceptually however, this is every bit as (un)safe as having a mutable vector and an index (which the borrow checker naturally allows). I'm just wondering if there's a way to work around this in Rust, hence the question. – SongWithoutWords Feb 03 '19 at 03:20
  • *this is every bit as (un)safe as having a mutable vector an index* — it is not. By using an index, you never hold a reference into the vector that you guarantee will not change at the same time that you attempt to change the value. – Shepmaster Feb 03 '19 at 03:22
  • 1
    I guess I've just always thought of holding an immutable reference as "I will not change this value through this reference", but I guess with Rust's stronger guarantees this becomes "no mutable reference exists to this value or any of its components within this scope" – SongWithoutWords Feb 03 '19 at 03:24
  • 1
    You may also be interested in [Situations where Cell or RefCell is the best choice](https://stackoverflow.com/q/30831037/155423) or [Need holistic explanation about Rust's cell and reference counted types](https://stackoverflow.com/q/45674479/155423). Outside of your direct question, using a `Cell` or a `RefCell` might allow you to solve your problem in exchange for moving the borrow checking to runtime. – Shepmaster Feb 03 '19 at 03:25
  • 1
    *with Rust's stronger guarantees* — yes, these are called [The Rules of References](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#the-rules-of-references). – Shepmaster Feb 03 '19 at 03:27

0 Answers0