Rust Generics

less than 1 minute read

Generics typically start with <T> by convention and are use to generalize types.

If we wanted to use the same 3-axis accelerometer struct for both raw data and floating point data we could use:

struct Accelerometer<T>{
	x: T,
	y: T,
	z: T,
}
//...
let raw_data = Accelerometer { x: 10_i16, y: -23_i16, z: 9812_i16 };
let data = Accelerometer { x: 0.01, y: -0.023, z: 9.812 };

Generics can be used with enums:

enum ImuSensor<T, U, V> {
	Accelerometer<T>,
	Gyroscope<U>,
	Magnetometer<V>,
};

Implementing structs or enums with Generics:

impl<T> Accelerometer<T>
where T: std::ops::Add { //..

Functions can take generic types too:

fn calculate_angle<T>(x: T, y: T) -> f32 { //..

Generic types should have constraints applied to ensure some interfaces are avaliable to them:

fn calculate_angle<T: std::convert::Into<f32>>(x: T, y: T) -> f32 { //..
// Alternatively:
fn calculate_angle<T>(x: T, y: T) -> f32
where
	T: std::convert::Into<f32>
{ //..