Suppose I want to create some type that wraps some other generic type, like so:
struct MyWrapper<T> {
pub inner: T,
}
Now I want my type to have a method if the inner type satisfies a specific bound. For example: I want to print it (in this example without using fmt
traits for simplicity). To do this I have two possibilities: adding a bound to the impl
or to the method itself.
Method Bound
impl<T> MyWrapper<T> {
pub fn print_inner(&self) where T: std::fmt::Display {
println!("[[ {} ]]", self.inner);
}
}
When calling this function with a MyWrapper<()>
I get:
error[E0277]: `()` doesn't implement `std::fmt::Display`
--> src/main.rs:20:7
|
20 | w.print_inner();
| ^^^^^^^^^^^ `()` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
|
= help: the trait `std::fmt::Display` is not implemented for `()`
Impl Bound
impl<T: std::fmt::Display> MyWrapper<T> {
pub fn print_inner(&self) {
println!("[[ {} ]]", self.inner);
}
}
Calling it incorrectly again, gives:
error[E0599]: no method named `print_inner` found for type `MyWrapper<()>` in the current scope
--> src/main.rs:19:7
|
1 | struct MyWrapper<T> {
| ------------------- method `print_inner` not found for this
...
19 | w.print_inner();
| ^^^^^^^^^^^
|
= note: the method `print_inner` exists but the following trait bounds were not satisfied:
`() : std::fmt::Display`
My question is: what is more idiomatic? Are there semantic differences (aside from lifetime stuff with traits, explained here)? Are there differences apart from the compiler message?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…