HiveBrain v1.2.0
Get Started
← Back to all entries
patternrustMinor

Should trait bounds be duplicated in struct and impl?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
structduplicatedshouldandimpltraitbounds

Problem

The following code uses a struct with generic type. While its implementation is only valid for the given trait bound, the struct can be defined with or without the same bound. The struct's fields are private so no other code could create an instance anyway.

trait Trait {
    fn foo(&self);
}

struct Object {
    value: T,
}

impl Object {
    fn bar(object: Object) {
        object.value.foo();
    }
}


Should the trait bound for the structure should be omitted to conform to the DRY principle, or should it be given to clarify the dependency? Or are there circumstances one solution should be preferred over the other?

Solution

It really depends on what the type is for. If it is only intended to hold values which implement the trait, then yes, it should have the trait bound e.g.

trait Child {
    fn name(&self);
}

struct School {
    pupil: T,
}

impl School {
    fn role_call(&self) -> bool {
        // check everyone is here
    }
}


In this example, only children are allowed in the school so we have the bound on the struct.

If the struct is intended to hold any value but you want to offer extra behaviour when the trait is implemented, then no, the bound shouldn't be on the struct e.g.

trait GoldCustomer {
    fn get_store_points(&self) -> i32;
}

struct Store {
    customer: T,
}

impl Store {
    fn choose_reward(customer: T) {
        // Do something with the store points
    }
}


In this example, not all customers are gold customers and it doesn't make sense to have the bound on the struct.

Code Snippets

trait Child {
    fn name(&self);
}

struct School<T: Child> {
    pupil: T,
}

impl<T: Child> School<T> {
    fn role_call(&self) -> bool {
        // check everyone is here
    }
}
trait GoldCustomer {
    fn get_store_points(&self) -> i32;
}

struct Store<T> {
    customer: T,
}

impl<T: GoldCustomer> Store {
    fn choose_reward(customer: T) {
        // Do something with the store points
    }
}

Context

Stack Overflow Q#49229332, score: 17

Revisions (0)

No revisions yet.