patternrustMinor
Should trait bounds be duplicated in struct and impl?
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.
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?
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.
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.
In this example, not all customers are gold customers and it doesn't make sense to have the bound on the struct.
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.