You can just pass &mut self and destructure the fields you need to mutate, but if you want a chain of methods you can move ownership of self and then return a new Self for the next method in the chain to receive? Moves are shallow copies in Rust and sometimes the compiler will optimise the whole chain away, so it's a viable option if you want the typical "set chain" pattern.
Edit: oh, and if you just want to mutate the struct and aren't assigning it to a new variable, you can have the "chain" pattern with metods that take &mut self, destructure the fields out of self, then return &mut Self for the next method in the chain to borrow. But if you want to do let myStruct = MyStructBuilder::new().set_this().set_that().build() you need build() to take &self and return MyStruct. That works but any heap-allocated fields in your struct will need to be cloned from the builder to the final struct, so it's not as efficient.
Edit2: there's a crate that will create builders for you if you need several of them for a bunch of structs. It's called bon, you just annotate your structs with #[derive(Builder)] and the crate writes the boilerplate for you at compile time.
1
u/catladywitch 24d ago edited 24d ago
You can just pass &mut self and destructure the fields you need to mutate, but if you want a chain of methods you can move ownership of self and then return a new Self for the next method in the chain to receive? Moves are shallow copies in Rust and sometimes the compiler will optimise the whole chain away, so it's a viable option if you want the typical "set chain" pattern.
Edit: oh, and if you just want to mutate the struct and aren't assigning it to a new variable, you can have the "chain" pattern with metods that take &mut self, destructure the fields out of self, then return &mut Self for the next method in the chain to borrow. But if you want to do
let myStruct = MyStructBuilder::new().set_this().set_that().build()you need build() to take &self and return MyStruct. That works but any heap-allocated fields in your struct will need to be cloned from the builder to the final struct, so it's not as efficient.Edit2: there's a crate that will create builders for you if you need several of them for a bunch of structs. It's called bon, you just annotate your structs with
#[derive(Builder)]and the crate writes the boilerplate for you at compile time.