wyer33
wyer33

Reputation: 6340

How to overload a function or method on a generic type inside of a Vec?

I need a function that operates on a vector that has a default implementation as well as specialized implementations for a few different types.

I can accomplish this:

trait Foo<T>
where
    T: std::fmt::Display,
{
    fn foo(&self) {
        println!("Generic: {}", self.vectorize()[0]);
    }
    fn vectorize(&self) -> &Vec<T>;
}

impl Foo<f32> for Vec<f32> {
    fn vectorize(&self) -> &Vec<f32> {
        self
    }
}

impl Foo<f64> for Vec<f64> {
    fn foo(&self) {
        println!("Specialized: {}", self[0]);
    }
    fn vectorize(&self) -> &Vec<f64> {
        self
    }
}

fn main() {
    vec![1.2_f32, 2.3].foo();
    vec![3.4_f64, 4.5].foo();
}

The strategy is to define a trait with a default implementation and then specialize it when required. My problem is that we really need to know that the type is a Vec and therefore need this helper function vectorize to obtain the correct type. This makes things a bit verbose and I'd like to do this better.

I don't really care if there's a trait or not; I just need a function that gets specialized on the different underlying Vec type and the only way I know how to do this is through the use of a trait.

Upvotes: 1

Views: 188

Answers (1)

gsmith
gsmith

Reputation: 81

You want to directly access an indexed value of the vector in your trait, which is a behavior defined by the Index trait of the std and is implemented by the Vec struct. So you just need to specify that the Foo trait require the Index trait to be implemented as well.

use std::ops::Index;

trait Foo<T>: Index<usize, Output = T>
where
    T: std::fmt::Display,
{
    fn foo(&self) {
        println!("Generic: {}", self[0]);
    }
}

impl Foo<f32> for Vec<f32> {}

impl Foo<f64> for Vec<f64> {
    fn foo(&self) {
        println!("Specialized: {}", self[0]);
    }
}

fn main() {
    vec![1.2_f32, 2.3].foo();
    vec![3.4_f64, 4.5].foo();
}

Upvotes: 1

Related Questions