Home > front end >  Implement a generic trait but only for a specific type
Implement a generic trait but only for a specific type

Time:08-03

I'm trying to wrap a generic layer with a type specific layer that crops values to a range. I want the 2 layers to implement the same base_layer trait but the wrapping layer would only be valid for the f32 type. Is this possible in Rust or I'm I trying to do something really non-idiomatic rust object oriented stuff.

Example:

struct Layer<T> {
    val: Vec<T>,
}

trait BaseLayer<T> {
    fn get_mut(self: &mut Self, index: u32) -> Option<&mut T>;
}

impl<T> BaseLayer<T> for Layer<T> {
    fn get_mut(self: &mut Self, index: u32) -> Option<&mut T> {
        self.val.get_mut(index as usize)
    }
}

struct Rangedf32Layer {
    layer: Layer<f32>,
    max: f32,
    min: f32,
}

And I want to do something like:

impl<T> BaseLayer<T> for Rangedf32Layer {
    fn get_mut(self: &mut Self, index: u32) -> Option<&mut T> {
        self.layer.get_mut(index).map(|v| {
            *v = v.clamp(self.min, self.max);
            v
        })
    }
}

but ofc get:

mismatched types
expected enum `Option<&mut T>`
   found enum `Option<&mut f32>`

And changing the output type would break the trait implementation.

 -> Option<&mut f32>

Gives:

method `get_mut` has an incompatible type for trait

How would I go about doing this?

CodePudding user response:

Instead if trying to make your impl generic, you can instead pass the trait a concrete type:

impl BaseLayer<f32> for Rangedf32Layer {
    fn get_mut(self: &Self, index: u32) -> Option<&mut f32> {
        self.layer.get_mut(index).map(|v| {
            *v = v.clamp(self.min, self.max);
            v
        })
    }
}
  • Related