Currently we have this (blob reference, master is here) which contains an example of trait use to share implementations.
trait Printable {
// Default method implementation
fn print(&self) { println!("{:?}", *self) }
}
impl Printable for int {}
impl Printable for String {
fn print(&self) { println!("{}", *self) }
}
impl Printable for bool {}
impl Printable for f32 {}
The example defines a trait Printable
, which prints things using `"{:?}" so it works on multiple types. AFAIK this is discouraged generally, and one thing that we could use is an example of reuse that doesn’t use type wildcards in a print statement, but ideally something a bit more idiomatic. Can we come up with a better implementation than print wildcards, or perhaps just find a reference implementation where this is useful in practice?
Besides that, there are a few questions to answer with respect to sharing implementation with traits that I’d like to see discussion about.
When is using traits to share implementations a good idea?
Presumably this is useful for part of the reason that inheritance in object-oriented design is useful: you can write the same code once, reuse it many times, and override it if necessary. Anything else?
When is this a bad idea?
A comment in the guidelines suggests discouraging this in a way that is publicly exposed, but this is marked [OPEN] so it could probably use more discussion.
I figure this is related to principles of information hiding: the user of some code shouldn’t have to care about how it’s implemented or whether I change it later to a custom implementation.
With respect to defining “publicly exposed”, I can think of two ways that this could be “public”:
- The caller/user of your code somehow knows that you used a trait to share the implementation of something.
- You have declared the trait
pub
, so the user may use the default implementation themselves.