Writing Javascript in Rust ... almost

In this case, you don't want to wrap them in Mutex or RefCell, it's that simple.

Yep, a plain Arc<MyStruct> will only allow taking references to MyStruct and nothing will be able to change it. It's because Arc's only allow taking immutable references that you must use a Mutex to allow mutation. The Mutex allows immutable references to mutate the value inside the mutex by lock()-ing it.

So Mutex is where you granted permission for mutating an object that is behind a read-only reference.

As far as I can tell at the moment there has to be a "mut" in there some where. Else nobody could ever write anything into the MyStruct that gets created.

But I did not create that MyStruct directly. I delegated it to RefCell at the bottom of the rabbit hole.

I get the feeling that if I followed that rabbit hole I would find a "mut" eventually?

Yes/No ?

I think the end of the rabbit whole is this UnsafeCell::get function that takes an immutable reference to &self, but returns a mutable pointer. That's fundamentally unsafe and bypasses Rust's normal rules, but this allows other structs like RefCell to achieve interior mutability.

Ha ha!

I don't care how "unsafe" it is under the hood. I trust that whoever wrote it that nothing bad will happen when I use it.

It would be really cool if someone could point to the line of code under all this and say "Look, there, that is the 'mut' you are looking for"

1 Like

Exactly, that's ( kind of ) why unsafe is there, to be hidden behind safe by people who know what they are doing.

All you have to do is click the [src] link on Docs.rs :slight_smile: :

    pub const fn get(&self) -> *mut T {
        // We can just cast the pointer from `UnsafeCell<T>` to `T` because of
        // #[repr(transparent)]. This exploits libstd's special status, there is
        // no guarantee for user code that this will work in future versions of the compiler!
        self as *const UnsafeCell<T> as *const T as *mut T
    }
1 Like

As you were writing that, that is exactly what I was doing.

Sure enough there it is "as *mut T"

Thanks, I can rest now.

Although it boggles my mind how people actually write such things, in the swamp of generics and traits and so on.

1 Like

Well, someone had to do it for the v1 release, otherwise multi-threading would've been in a sad state with absolutely no way to share mutable state between threads, except for spawning (moving data in) and joining (moving data out) threads.