rust-lang / book

The Rust Programming Language
https://doc.rust-lang.org/book/
Other
15.11k stars 3.4k forks source link

Book fails to mention usage of const in traits #3410

Open ndim opened 1 year ago

ndim commented 1 year ago

URL to the section(s) of the book with this problem: book: https://doc.rust-lang.org/book/ch10-02-traits.html#default-implementations source: src/ch10-02-traits.md

Description of the problem:

When describing traits, the book only describes fn items as part of the trait. However, it appears that const items can also be part of a trait, and be especially useful in connection with default implementations of fn items.

Suggested fix:

I would have found it helpful if an example of the following type and possibly more discussion about const in trait would have been in the "Default Implementations" section of src/ch10-02-traits.md.

If using const inside a trait is considered too advanced for inclusion in the basic chapter on traits, mentioning that const can be a part of a trait might also fit into src/ch19-03-advanced-traits.md.

I might also be wrong about this belonging in the book (I am too new to Rust to judge that). const-in-trait just seems to solve a not too uncommon problem for someone writing software for about the last 25 years, and const-in-trait not being mentioned in the book at all surprised me.

Minimum working example:

trait Multiplier {
    const MULTIPLIER: u32;
    fn mul(value: u32) -> u32 {
        value * Self::MULTIPLIER
    }
}

struct Times5;
impl Multiplier for Times5 {
    const MULTIPLIER: u32 = 5;
}

struct Times23;
impl Multiplier for Times23 {
    const MULTIPLIER: u32 = 23;
}

fn main() {
    println!("Hello, world!");
    assert_eq!(40, Times5::mul(8));
    assert_eq!(69, Times23::mul(3));
}

I ran into this when converting different decibel values to and from u32 values sent to and received from a USB device, and needing to parse such values from strings as command line arguments. The three device parameters all use different numeric ranges, but they all have a common behaviour for parsing the CLI argument string into a numeric value and converting from f64 decibel value to the u32 integer value the device uses and vice versa.

I found const-in-trait somewhere on the internet, wondered why the book did not mention that at all, and then dav1d on the #rust IRC channel said that it was ok to use const-in-trait, so I wrote this issue.

I might come up with a better example for illustrating const-in-trait which explains it better and in a more useful manner than the trait Multiplier example, but is not as complex as the three decibel conversions.

chriskrycho commented 6 months ago

This is an interesting one. It’s definitely a valuable feature to know about, but the book also can't be exhaustive. I flagged it for us to think about as we look at the next revision, but I think it is probably one of those things that is advanced enough and relatively rare enough that it doesn't make sense to put in the main book! We'll see.