Rust Brain Teasers: Doubling the right value (page 69?)

The page number is absent for the “card” pages unfortunately, but it’s before page 70.

println!("2 * 4 = {}", double_it(2));

should be

println!("2 * 4 = {}", double_it(4));

It won’t change the outcome, but I’d put a “4” at least just for the sake of clarity. :wink:

I must admit that missing features like overloading and default parameters requires some boilerplate code sometimes, it’s sad. Hopefully they’ll get around to providing that in a distant future but it seems to require a tremendous amount of discussion before reaching any decision.

In comparison, Kotlin has its development started slightly later by a small team (at Jetbrains) and is now much more flexible. It also includes more libraries, for which Rust must rely on external crates (and are for the most part yet in beta stage…).

Those are the little drawbacks of this otherwise awesome language.

@herbert I finished the book, it’s really well done and a good way to learn or review features of the language!

I reported a few potential issues, but they’re really just minor points.

Hi!

Sorry for the slow replies, I’ve been having a “fun” week with an unwell baby. I’m glad you enjoyed the book!

Rust made the decision not to implement operator overloading, so I wouldn’t expect that to appear. It caused enough confusion in C++ land over the years that I think the core team want to avoid going there. With that said, you can setup something similar for most operators. You can implement most of the operations yourself with std:ops::, for example std::ops::Add. The following article has an example of implementing addition for Point structures:

Default parameters are something I wish the language had, too. I think that the core team shied away from them for the same reason - in C++ it can become confusing. There are RFCs towards named parameters ( e.g. Pre-RFC: Named arguments - language design - Rust Internals ), which would lay the groundwork for a non-confusing way to do it; they could add .. or ..default() to indicate that defaults are in use. (Rust tries to be explicit about everything).

When you have a long set of possible parameters and want to offer defaults, the current way to do it is to implement a struct, and then implement Default for it. For example (not tested, just typing it into the thread window):

struct MyLongParameters {
    paramOne: String,
    paramTwo: i32,
    paramThree: u32,
}

impl Default for MyLongParameters {
    fn default() -> MyLongParameters {
        MyLongParameters { paramOne: "Hello".to_string(), paramTwo: -12, paramThree: 4 }
    }
}

Once that’s there, you can have a function accept the structure as an argument and use the structure defaulting mechanism:

myFunction(MyLongParameters { paramOne: "World".to_string(), ..Default::default() }

IIRC, you can just use ..default() (the Bevy engine does that) - but I’m not 100% sure.

Hope that helps!

Thanks for the reply. The above were just random comments from me; there is no urgency at all so no worries, and sorry to hear about the health issue, I know it can take a lot of energy :wink:

Yes, there are a few techniques for the default parameters, the struct could be interesting and maybe not too cumbersome. I’ve seen a few macros, too, like default-args or the ill-named duang (there are others), but I was not entirely convinced yet.

I just wanted to add that there’s a typo in the section on generics (PDF p. 71), point #2: “…The first constraint requires that T implement std::ops::Mul, meaning the type must support the addition operator…”

…should be the multiplication operator, yes?