Using `impl` with default types


#1

In this, the below example is there for using impl with stuct as below:

struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}

impl Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }
}

fn main() {
    let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
    println!("{}", c.area());
}
// This will print 12.566371

Is there a way to apply impl to standard type, lets say for example I need to write dbl to give me the double of the int, I need to write something like:

impl i32 {
    fn dbl(&self) -> i32 {
        self * self
    }
}

fn main() {
    let x: i32 = 4;
    println!("The double of {} is {}", x, x.dbl());
}
// Expected output: The double of 4 is 16

But I got the below error:

enter image description here


#2

You can create a trait and implement in on the primitive (or any.)

trait Dbl {
    fn dbl(&self) -> i32;
}
impl Dbl for i32 {
    fn dbl(&self) -> i32 {
        self * self
    }
}

#3

Thanks a lot, it is what I want.


#4

HI @jonh
Is there a way I can implement the same for Vec, I tried as below but got error:

trait  AvgExt {
    fn average(&self) -> f32;
}
impl AvgExt for Vec<T>{

} 

I need to make AverageExt for the Vec that can give me the average of the vec’s numbers!


#5

Is there a reason not to just write functions?

fn dbl(x: f64) -> f64 {
  x*2.0
}
println!("The double of {} is {}", x, dbl(x));

#6

The “extension trait” idiom works for any type. You’re only getting an error because, as the error message says, impl AvgExt for Vec<T> is invalid because T is not a type defined anywhere.

I assume you want to say “Vec of any type”, and the syntax for that is impl<T> AvgExt for Vec<T>.


But as @droundy said, it’s usually better to just use an ordinary function. There’s not much benefit to an extension trait unless you’re also writing some code that’s generic over that trait.


#7

To add, you’ll also need more bounds on T to allow performing operations on it (eg sum, div, and converting to f32). The num crate is useful here as it has a bunch of traits and impls for the primitive types to this effect.