Trait with associated type which is either reference or value

I want to write a trait like that:

pub trait Value {
    type Argument;

    fn initialize(arg: Self::Argument) -> Self;
}

impl Value for u64 {
    type Argument = u64;

    fn initialize(arg: u64) -> u64 {
        arg
    }
}

impl Value for String {
    type Argument = &str; // ???
    
    fn initialize(arg: &str) -> String {
         arg.to_string()
    } 
}

Here is a link to playground: Rust Playground

How can I achieve this, or is this simply not possible?

You'd either need to add a lifetime parameter to Self::Argument:

pub trait Value {
    type Argument<'arg>;

    fn initialize(arg: Self::Argument<'_>) -> Self;
}

impl Value for u64 {
    type Argument<'arg> = u64;

    fn initialize(arg: Self::Argument<'static>) -> u64 {
        arg
    }
}

impl Value for String {
    type Argument<'arg> = &'arg str;

    fn initialize<'arg>(arg: Self::Argument<'arg>) -> String {
        arg.to_string()
    }
}

Playground,

or the trait itself:

pub trait Value<'a> {
    type Argument;

    fn initialize(arg: Self::Argument) -> Self;
}

impl Value<'static> for u64 {
    type Argument = u64;

    fn initialize(arg: Self::Argument) -> u64 {
        arg
    }
}

impl<'a> Value<'a> for String {
    type Argument = &'a str;

    fn initialize<'arg>(arg: Self::Argument) -> String {
        arg.to_string()
    }
}

Playground.

3 Likes

It works, thank you!

1 Like