Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rust: conditional trait inheritance

Tags:

rust

traits

For example, I want to write the trait for containers in Rust:

trait Container: Default {
    type ValueType;
}

But also I want that all Containers also can be Cloned only when Container::ValueType can be Cloned:

// not Rust code
trait Container: Default + Clone if Self::ValueType: Clone {
    type ValueType;
}

Of course, I could conditionally implement Clone trait for the concrete container itself:

struct MyVec<T> {}

impl<T: Clone> Clone for MyVec<T> {/**/}

or use derive(Clone), but I want to express my intention for Container trait, not for implementing types.

like image 283
Michael Galuza Avatar asked Oct 14 '25 17:10

Michael Galuza


1 Answers

This similar syntax exists:

trait Container: Default + Clone where Self::ValueType: Clone {
                              // ^^^^^
    type ValueType;
}

But it isn't conditional, Container can only be implemented for types that statisfy all constraints: Default, Clone, and Self::ValueType is Clone.


I'm not sure this would be useful. Rust trait constraints are explicit, meaning you can't use something unless the constraint is there. So you'd have to include them in the constraints anyway.

fn use_container<C: Container>(c: C)
where
    C: Clone,
    C::ValueType: Clone
{
  let _ = c.clone();
  let _ = c.get_element().clone();
}

And you have to implement Clone on the concrete types regardless.

If your goal is just to indicate that "for implementations of Container if the elements are Clone then the container should be clone", the prevailing pattern in idiomatic Rust is to only constrain what you need when you need it. (i.e. if a function needs to clone the container, constrain on C: Clone; if a function only needs to clone an element, constrain on C::ValueType: Clone).

like image 133
kmdreko Avatar answered Oct 18 '25 06:10

kmdreko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!