Search code examples
rusttraits

Rust traits with constant field defined by implementation


The Setup

I want to be able to define a trait such that any struct implementing the trait not only has to implement the functions, but also has to specify values for certain constants. So maybe something like:

trait MyTrait {
    const MY_CONST: u8;
    fn foo();
    fn bar();
}

And then the struct would look something like:

struct MyFirstStruct {
    const MY_CONST: u8 = 42;
    ...
}
impl MyTrait for MyFirstStruct {
    fn foo() {...}
    fn bar() {...}
}

Such that when I later implement MySecondStruct, MyThirdStruct, they can each have different values for MY_CONST, but every instance of MyFirstStruct will have the same value of MY_CONST, and every instance of MySecondStruct will also have the same value of MY_CONST (Which may or may not be different to the value of MY_CONST for MyFirstStruct)

Is this possible?

What I've tried

I've tried various combinations of specifying the constant in the impl MyTrait for MyFirstStruct block, specifying it in the struct MyFirstTrait block, and can't seem to figure it out.

Searching online seems to always land be on the rust book (which doesn't describe something like this), rust by example, the advanced traits rust book chapter, or this webpage on traits which has a frustratingly small section on Trait constants which seems to imply this is possible, maybe.

I've thought about using function definitions like getMY_CONST() which would be implemented to just return MY_CONST, but that seems like an ugly hack that I'd rather avoid if possible.

If this isn't possible, other ways of making this work are appreciated, I'm still getting started on the rust adventure :) .


Solution

  • Traits can have associated constants, and the syntax in the trait definition is exactly as you guessed. Setting the value for a particular trait is part of the trait implementation, though, and not part of the struct definition.

    trait MyTrait {
        const MY_CONST: u8;
        fn foo();
        fn bar();
    }
    
    struct MyFirstStruct;
    
    impl MyTrait for MyFirstStruct {
        const MY_CONST: u8 = 42;
        fn foo() {}
        fn bar() {}
    }