Struct member access style in Rust

I found that different libraries provide getters to access even public struct members:

struct.member().child().feature()

but following code looks simpler imho:

struct.member.child.feature()

Of course, there is different goals for both implementations, but anyway, is any recommendation in Rust that prefer getters and not direct pub members access? Or that's my luck to see getters everywhere, even API has pub access to the struct members

Why? If it's public, there is no point to providing a getter method. If the getter is supposed to enforce invariants, then making the field public is probably a bug.

As far as I know, that's it. The only reason you want a getter method is to enforce invariants. If I have &mut Struct, I can replace any of its public fields and that might cause bugs that the type author wants to avoid.

An example of such an invaiant could be "you can have &mut Struct, but replacing its fields breaks things. So you must use Struct::child(&self) instead." Now even if I have &mut Struct, I cannot get a &mut Child from its child() method, so I cannot break the invariants on Struct.

1 Like

Your luck. The actual recommendation is to avoid setters and getters where possible, because those get in the way of borrow splitting. It's odd to have a getter for a public field.

8 Likes

It depends. You might want to enforce invariants for users of your crate and force them through a getter. But inside your project you may use direct field access to allow for e.g. borrow splitting for internal purposes. Thus having a getter for a pub(crate) field: type, may be a valid use case.

1 Like

If replacing content of a field is not safe (like Vec.len), then the field must be private, and that makes a getter necessary.

Otherwise public fields are better, since they make borrow checking more precise and flexible.

1 Like

Thanks guys for opinion, it was a doubt just because of Rust is modern language, and some old principles not recommend as deprecated. Now I understand, that free to chose here, according to the app implementation.

Yes, that's very common: within the crate you access the field, and outside the crate you use a getter because accessing the field directly is not possible (due to it not being public).

1 Like

It's not because Rust is modern, it's specifically because directly accessing fields works better with the borrow checker.

1 Like

By thanks for your comments, seems I found the answer for another my subject. Seems that really direct member access would better than &getters usage (where it's not really wanted), because at least make compilation process faster (not overload borrow checker)

That's not right. Getters should not be slowing down compilation very much. And neither getters nor reference counted types would slow down the borrow checker.

Getters are not related to borrow checking performance. Rather, using getters can cause borrow checking to fail, meaning the program doesn't compile. This is because self is borrowed when calling a getter, which is equivalent to borrowing all fields of self. By accessing a field directly, without a getter, only that one field is borrowed. This reduces the chances of conflicts between borrows.