You can also make the parameters of a struct generic

The following code works only for u32 (and not for i32, f32)

struct Rect {
    width: u32,
    height: u32,
}

impl Rect {
    pub fn area(&self) -> u32 {
        self.height * self.width
    }
}

fn main() {
    let r = Rect {
        width: 10,
        height: 20
    };

    println!("{}", r.area());
}

To convert this code to work for all these types, we can do the following

struct Rect<T> {
    width: T,
    height: T,
}

impl<T: std::ops::Mul<Output = T> + Copy> Rect<T> {
    pub fn area(&self) -> T {
        return self.height * self.width
    }
}

fn main() {
    let r = Rect {
        width: 10,
        height: 20
    };

    println!("{}", r.area());
}

Why two <T>s ?

The first one is defining the generic type with a trait bound to the Copy + Mul trait.

The second one is telling that this implementation is for.

For example, we can implement an area function saparately just for u32 Rects.

impl Rect<u32> {
    pub fn area(&self) -> u32 {
        return self.height * self.width
    }
}