我正在读“编程Rust”一书,并了解了Rust的特征和泛型类型。我发现类型边界可以放在特征的方法上。然后我构造了以下特征并为结构实现了它。
use std::fmt::Display;
trait Test<T> {
fn show(&self)
where
T: Display;
fn test(&self);
}
struct S<T> {
field: T,
}
impl<T> Test<T> for S<T> {
fn show(&self)
where
T: Display,
{
println!("My field: {}", self.field);
}
fn test(&self) {
println!("Just for test");
}
}
以下代码无法按预期编译:
struct R;
fn main() {
let s = S { field: R {} };
s.show();
}
但是下面的代码将编译并运行。
struct R;
fn main() {
let s = S { field: R {} };
s.test();
}
当s
定义为S { field: R{} }
时,Rust不应该拒绝代码吗?这是否意味着s
是部分实施S
的trait T
的一个例子?
Rust特征可以部分实施吗?
没有。全部或全部没有。
但是为什么一个代码编译但另一个代码不编译。
原因是show
的额外限制
fn show(&self) where T: Display;
这意味着,当你想调用这个方法时,你的T
必须实现Display
。如果没有实现,则无法调用它。
例如,Rusts“泛型”的工作方式与C ++不同。
在C ++中你有SFINAE(替换失败不是错误)。这是一种duck typing。
Rust在边界上工作,这意味着你必须指定你的“通用”必须使用这些函数的特性。在这种情况下,您可以调用Display::fmt
,因为您指定了T
必须实现该特征。
没有为test
方法指定此绑定,因此您可以使用您想要的任何类型调用它。