Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically derive Add, Mul, Ord, etc. for a numeric type [duplicate]

What's the simplest way to create a custom type that behaves like a number?

I want type-checking that prevents mixing different units in my program, but I still want to be able to easily perform calculations on the type without casting back and forth (similar case to custom Centimeters and Inches types).

If I create:

struct Centimeters(f64);

then I have to implement Add, Mul, Ord and lots of other traits manually. That's a lot of boilerplate, and copy&pasting of this code creates a risk of breaking basic arithmetic in the program :)

Unfortunately #[derive(Add, Sub, …)] doesn't seem to be supported. Is there another standard trait/type/crate that could achieve similar effect?

like image 737
Kornel Avatar asked Aug 09 '15 10:08

Kornel


1 Answers

Units of Measurement

You should have a look at https://crates.io/crates/measurements. That crate contains definitions for many units of measurement like centimeters, feet, etc.

Implementing traits for your newtypes

There are now some crates that make it really easy to implement Add, Mul, etc. for your newtypes.

derive_more

// This needs rust in the 2018 edition
extern crate derive_more;
use derive_more::{Add, Mul};

#[derive(Add, Mul)]
struct Centimeters(i32);

newtype_derive

custom_derive! {
  #[derive(NewtypeAdd, NewtypeMul)]
  pub struct Centimeters(i32);
}

Traits with your own macro

This answer has a nice macro to help you implement traits for your newtypes.

like image 51
FlyingFoX Avatar answered Oct 18 '22 17:10

FlyingFoX