// 定义自定义trait
trait MyTrait {
fn do_something(&self);
}
// 定义泛型结构体,类型参数T需要实现Clone
struct MyStruct<T: Clone> {
data: T,
}
// 定义泛型函数,参数需要实现Clone和MyTrait
fn process<T: Clone + MyTrait>(input: MyStruct<T>) {
let cloned = input.data.clone();
input.data.do_something();
cloned.do_something();
}
fn main() {
// 定义一个实现了Clone和MyTrait的类型
struct MyType;
impl Clone for MyType {
fn clone(&self) -> Self {
MyType
}
}
impl MyTrait for MyType {
fn do_something(&self) {
println!("Doing something!");
}
}
let my_struct = MyStruct { data: MyType };
process(my_struct);
}
trait bounds的作用
- 类型约束:在
MyStruct<T: Clone>
中,T: Clone
表示类型参数T
必须实现Clone
trait。这确保了MyStruct
内部的数据可以被克隆,比如在process
函数中let cloned = input.data.clone();
语句能够正常工作。
- 功能限制:在
process<T: Clone + MyTrait>
中,T: Clone + MyTrait
意味着类型参数T
不仅要实现Clone
trait,还要实现MyTrait
。这保证了在process
函数内部,可以调用input.data.do_something()
以及克隆后cloned.do_something()
。
确保类型的一致性
- trait实现:通过在使用泛型的地方明确指定trait bounds,编译器会在编译时检查类型参数是否满足这些trait的实现。例如在
main
函数中定义MyType
时,必须为其实现Clone
和MyTrait
,否则编译器会报错。
- 编译时检查:Rust的类型系统在编译阶段进行详尽的类型检查,确保所有泛型代码在实际使用时,类型参数满足所有指定的trait bounds,从而保证了类型的一致性。