Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't newtypes use the traits from the inner type?

Tags:

rust

newtype

In rust 1.0.0-nightly, this code works fine:

fn main() {
    let x = 10f64;
    let y = 20f64;
    let z = x + y;
    println!("z = {}", z);
}

But if I try to use a newtype (according to the rust book):

struct Metres(f64);

fn main() {
    let x = Metres(10f64);
    let y = Metres(20f64);
    let z = x + y;
    println!("z = {}", z);
}

I get this compiler error:

test.rs:6:13: 6:18 error: binary operation `+` cannot be applied to type `Metres`
test.rs:6     let z = x + y;
                      ^~~~~
error: aborting due to previous error

Since Metres is basically a f64, why can't the compiler use the same + operator, and create a new Metres object for z?

How can I use newtypes if I can't do simple things like adding and such? How are they "very useful" (as the book calls them)?

(There is an old question about this, but rust changes a lot, hence I'm reasking)

like image 962
Amandasaurus Avatar asked Jan 31 '15 13:01

Amandasaurus


1 Answers

The reason newtypes work this way is generally because you want to avoid the traits defined on the underlying type. For example, you could have Metres and Feet which both wrap f64 but define addition of Metres and Feet to do unit conversion, which plain f64 addition doesn't give you.

Of course, sometimes you do want the underlying trait implementation. Currently, you'd have to write a wrapper implementation yourself, but there is an RFC for the ability to generate these automatically: https://github.com/rust-lang/rfcs/issues/479

like image 197
Scott Olson Avatar answered Nov 15 '22 14:11

Scott Olson