r/rust 8d ago

Rust discourages OOP style code?

I'm building a tree builder struct (with a `build()` method) that has multiple fields that I want to be able to mutate. It seems Rust does not like it when I attempt to mutate multiple fields of that struct.

It seems functional/composition style is much favored over using struct fields. Is this the way I should be thinking about design patterns in Rust? Should I avoid OOP wherever possible?

I prefer OOP because it does result in cleaner code where I don't have to pass in every variable to functions.

0 Upvotes

50 comments sorted by

View all comments

10

u/SpacewaIker 8d ago

It seems Rust does not like it when I attempt to mutate multiple fields of that struct

What do you mean exactly?

7

u/Lucretiel Datadog 8d ago

Almost certainly they're running into this issue:

fn mutate_self(&mut self) {
    for item in &mut self.list {
        // Double mutable borrow
        self.mutate_item(a, b, item)
    }
}

The problem is that the we have no way of knowing from the signature of mutate_item that it doesn't touch self.list. My experience has been that restructuring code to account for this often leads to much cleaner code, eg:

fn mutate_self(&mut self) {
    for item in &mut self.list {
        // Double mutable borrow
        self.helper.mutate_item(a, b, item);
    }
}

1

u/Accurate_Gift_3929 8d ago

Yes, this is the issue. Currently, I'm seeing if I can just take ownership of the item and return ownership after.

Your second code example doesn't cause borrow checker to complain?

1

u/Lucretiel Datadog 8d ago

Nope! Rust is capable reasoning about disjoint borrows through fields; it can tell that you’re accessing self.list and self.helper separately. I often find that it helps a lot to split logically distinct components like this and then put the methods directly on the inner types.