在 impl 块或方法上指定 trait bound 更好吗? [英] Is it better to specify trait bound on the impl block or on the method?
问题描述
假设我想创建一些包装其他泛型类型的类型,如下所示:
Suppose I want to create some type that wraps some other generic type, like so:
struct MyWrapper<T> {
pub inner: T,
}
现在我希望我的类型有一个方法,如果内部类型满足特定的界限.例如:我想打印它(在这个例子中,为了简单起见,不使用 fmt
特征).为此,我有两种可能性:向 impl
或方法本身添加一个绑定.
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.
impl<T> MyWrapper<T> {
pub fn print_inner(&self) where T: std::fmt::Display {
println!("[[ {} ]]", self.inner);
}
}
当使用 MyWrapper<()>
调用此函数时,我得到:
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<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?
推荐答案
一个语义上的区别是,通过方法上的类型绑定,您可以部分实现一个特征:
One semantic difference is that with the type bound on the method you can partially implement a trait:
trait Trait {
fn f(self) where Self: std::fmt::Display;
fn g(self);
}
struct Struct<T>(T);
impl<T> Trait for Struct<T> {
fn f(self) where Struct<T>: std::fmt::Display {
println!("{}", self);
}
fn g(self) {
println!("Hello world!");
}
}
fn main() {
let s = Struct(vec![1]);
// f is not implemented, but g is
//s.f();
s.g();
}
如果您有许多具有不同类型边界的可选方法,这可能很有用,否则需要单独的特征.
This may be useful if you have many optional methods with different type bounds, which would otherwise require separate traits.
这篇关于在 impl 块或方法上指定 trait bound 更好吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!