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

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 newtype (according to rust ):

 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 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 cannot do simple things like adding and the like? How are they β€œvery useful” (as the book calls them)?

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

+6
source share
2 answers

The reason newtypes work this way is usually because you want to avoid the traits defined in the base type. For example, you may have Metres and Feet , which both wrap f64 , but define the addition of Metres and Feet to do unit conversion, which a simple addition to f64 does not give you.

Of course, sometimes you need an implementation of a basic attribute. Currently you will have to write a shell implementation yourself, but there is an RFC for the ability to generate them automatically: https://github.com/rust-lang/rfcs/issues/479

+9
source

As mentioned by Scott Olson, it is actually voluntary that the new types are not "degenerate" at their only sign. In the end, they are here to introduce a new type.

If all you need is a synonym that is slightly different, then you can use an alias like:

 type Metres = f64; 

However, you are losing the benefits of the new type:

 type Grams = f64; fn main() { let m = 10 as Metres; let g = 5 as Grams; println!("{}", m + g); // prints 15, see http://is.gd/IdYOEg } 
+5
source

Source: https://habr.com/ru/post/981804/


All Articles