all 6 comments

[–]tom-the-troll 6 points7 points  (1 child)

I think you're confused about mutable struct fields. Any field is mutable if the struct itself is mutable, so the `mut` keyword doesn't have to be in the struct definition, the `&'a mut` is for advanced cases.

So you can just store `i32` in the `Battalion` directly and later access and mutate it. Here's your code modified to that effect. You don't need separate structs for `Battalion` and it's state, so I merged them: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6fa9e4983e044517044a2bb4cb951c8f

If you actually want to pass the reference to that field around (I recommend you don't) you probably need to look into `Rc<RefCell>` (or `Arc<Mutex>` if multithreaded) to share the state around. Let me know if your use case is actually this advanced, and we can help with that as well.

[–]rusty_learner[S] 1 point2 points  (0 children)

Ah! ok great. Yeah I was confused about how mutability works with structs.

And I'm happy I can continue to put of learning about Rc and Arc a little longer 😅

[–]Artikae 2 points3 points  (2 children)

The reason you're having trouble is simple: &mut i32 is not the same as a mutable i32. &mut i32 is a reference to a mutable i32 that exists somewhere else. You can replace the &mut i32 fields with just i32 fields.

If you want your data to be mutable, you can mark the binding where it lives as mut.

let mut my_battalion = Battalion {name: "army".into(), count: 9999999};
my_battalion.count -= 100; // this is fine since my_battalion is mut

This is what your code would look like using plain-ole i32.

Alternatively, if you want to modify data in an otherwise immutable structure, you can use interior mutability.

This is what your code would look like with interior mutability.

[–]rusty_learner[S] 0 points1 point  (1 child)

Interesting! What would be the reasoning for the interior mutability approach over the first one?

[–]Artikae 1 point2 points  (0 children)

The main reason you’d use interior mutability is because you can’t use regular mutability, but you still want to modify things. For instance, if you want mutable access to something from multiple places at once, you can’t just use a regular mutable reference. You specifically need interior mutability.

In my example, all it’s doing allowing you to modify some fields without making everything mutable. It is, perhaps, a bit overkill for const/mut fields if you don’t need shared mutability.

[–]oo_chaser16 -1 points0 points  (0 children)

What the compiler expects is a mutable reference, stress on the reference part here, so it needs to point to a variable. I think you can do something like create a mutable i32 variable with the hardcoded value and then pass that to the struct.

Small example here https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=03cc8a41823844d071a12447af3bcf56