30
votes

Traits are used to group some functions to be implemented from a struct, but is it possible to access struct fields from within the trait?

I could imagine declaring fields inside the trait so that the fields are abstracted as well. I haven't found such a syntax; is there any other solution? Otherwise, it wouldn't be possible to have non-static methods using a trait, would it?

I know object oriented programming from C# and I'm playing around with Rust, trying to adapt the OOP functionality I already know from C#.

3

3 Answers

32
votes

This sounds like you're misunderstanding how traits work. Traits can't have fields. If you want to provide access to a field from a trait, you need to define a method in that trait (like, say, get_blah).

If you're asking whether you can access fields of a struct from within that struct's implementation of a trait, then yes. The struct knows it's own type, so there's no problem.

trait Pet {
    fn is_smelly(&self) -> bool;
}

struct Dog {
    washed_recently: bool,
}

impl Pet for Dog {
    fn is_smelly(&self) -> bool {
        !self.washed_recently
    }
}

If you're writing a default implementation of a trait (i.e. defining a method body within the trait), then no, you can't access fields. A default implementation can only use methods that are defined on the trait or in a super trait.

21
votes

It would be useful to define fields in a trait's default implementation, so a struct implementing the trait would always have the same fields.

Apparently, the Rust team thinks the same but it is still a work in progress according to this RFC. It's a big change and it has been postponed, so I think the short answer is: you can't do it yet, but you might be able to do it in the future.

For now, you'll have to make do with less powerful traits.

3
votes

You can make accessor function in default trait implementation, that must return field value/ref in child implementations, returning default value. Use it in other fn's in default implementation, and redefine accessor's in child implementation. Default implementation fn's will use redefined accessors as it's virtual fn's.