Associated Constants

With the associated_consts feature, you can define constants like this:

#![feature(associated_consts)] trait Foo { const ID: i32; } impl Foo for i32 { const ID: i32 = 1; } fn main() { assert_eq!(1, i32::ID); }
#![feature(associated_consts)]

trait Foo {
    const ID: i32;
}

impl Foo for i32 {
    const ID: i32 = 1;
}

fn main() {
    assert_eq!(1, i32::ID);
}

Any implementor of Foo will have to define ID. Without the definition:

#![feature(associated_consts)] fn main() { trait Foo { const ID: i32; } impl Foo for i32 { } }
#![feature(associated_consts)]

trait Foo {
    const ID: i32;
}

impl Foo for i32 {
}

gives

error: not all trait items implemented, missing: `ID` [E0046]
     impl Foo for i32 {
     }

A default value can be implemented as well:

#![feature(associated_consts)] trait Foo { const ID: i32 = 1; } impl Foo for i32 { } impl Foo for i64 { const ID: i32 = 5; } fn main() { assert_eq!(1, i32::ID); assert_eq!(5, i64::ID); }
#![feature(associated_consts)]

trait Foo {
    const ID: i32 = 1;
}

impl Foo for i32 {
}

impl Foo for i64 {
    const ID: i32 = 5;
}

fn main() {
    assert_eq!(1, i32::ID);
    assert_eq!(5, i64::ID);
}

As you can see, when implementing Foo, you can leave it unimplemented, as with i32. It will then use the default value. But, as in i64, we can also add our own definition.

Associated constants don’t have to be associated with a trait. An impl block for a struct or an enum works fine too:

#![feature(associated_consts)] fn main() { struct Foo; impl Foo { const FOO: u32 = 3; } }
#![feature(associated_consts)]

struct Foo;

impl Foo {
    const FOO: u32 = 3;
}