Xole82
Xole82

Reputation: 33

How to make generic type bounds for absolute value?

I'm currently learning rust and thought I'd test myself by implementing Absolute value on a simple generic type. Unfortunately, there is no Abs trait that I can implement myself (or that I can find), and without a trait, I'm not sure how I can make a bound to only accept types that can calculate the absolute value.

struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T>
where
    T: Abs, // This trait doesn't exist...
{
    fn abs(&self) -> Self {
        Point {
            x: self.x.abs(),
            y: self.y.abs(),
        }
    }
}

As an alternative, I can implement the method for Point<i32>, Point<f32> and all the other native types individually, or I could make a helper function which simply checks if a value is < 0 and manually converts it (using an ordering bound). I just feel I must be missing something obvious and there must be some kind of bound to make the generic function work with all appropriate types.

  1. Is there a trait suitable for implementing? Or is there a way to make a suitable bound?
  2. In either case, is there a way to implement this functionality without the Point<i32>, ... or manual abs helper function boiler plate above?
  3. (Subjective) How would you implement this?

Upvotes: 1

Views: 266

Answers (2)

starblue
starblue

Reputation: 56802

You can define your own trait:

trait Abs {
    fn abs(self) -> Self;
}

impl Abs for f64 {
    fn abs(self) -> Self {
        f64::abs(self)
    }
}

I do similar things in the lowdim crate.

Upvotes: 1

Xole82
Xole82

Reputation: 33

You can by using Signed trait from num:

use num::Signed;

struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T>
where
    T: Signed,
{
    fn abs(&self) -> Self {
        Self {
            x: self.x.abs(),
            y: self.y.abs(),
        }
    }
}

Upvotes: 2

Related Questions