Combining struct + trait


#1

I’m pretty sure this is a dumb question, but I just don’t get it:

I need a field of a certain type that provides a certain trait, but I don’t know the correct notation:

pub struct SomeStruct<T: Default + Clone> {
    field: Box<MyRequiredStruct<T> + MyRequiredTrait<T>>,
}

This gives me a “not a trait”-error for MyRequiredStruct.

MyRequiredStruct provides some implementation for all T: Default + Clone. MyRequiredTrait is only implemented for some special Ts. SomeStruct has to call methods of both implementations. My assumption was that a struct has some kind of inherent interface that can be used like a trait.


#2

Perhaps you want:

pub struct SomeStruct<T: Default + Clone>
    where MyRequiredStruct<T>: MyRequiredTrait<T>
{
    field: Box<MyRequiredStruct<T>>,
}

This may not need to be boxed either, unless you want that indirection for a large type, for instance.


#3

Or do you want something like (I’m on mobile so somewhat slim):

trait MySpecialTrait {}
struct MyRequiredStruct<T: Default + Clone>(T);

struct SomeStruct<T>(T);

impl<T: Default + Clone> SomeStruct<MyRequiredStruct<T>> {
  fn basic(&self) {}
}
impl<T: Default + Clone + MySpecialTrait> SomeStruct<MyRequiredStruct<T>>{
  fn special(&self) {}
}

The special method will only be available when the T is also MyRequiredTrait.


#4

Thanks, this is exactly what I was looking for!

I assumed the left-hand statement of a where had to be a newly introduced identifier, so I just did’t try that. I now understand the the where-clause is just a set of rules and not a set of declarations.

The Box is gone - it’s now obviously Sized :smiley:


#5

I considered this solution, but it wasn’t applicable to my current use-case. But good to know that this would have worked - went right into my toolbox :slight_smile:

Written on mobile? Respect!