观看B站软件工艺师杨旭的rust教程学习记录,有删减有补充
Trait 特质
trait
:共同行为,与其他类型共享的功能trait bounds
(约束):将泛型类型参数指定为实现了指定行为的类型trait
只有方法签名没有具体实现- 实现
trait
类型必须实现其方法
pub trait MyTrait {
fn method1(&self);
fn method2(&self, value: u32) -> u32;
}
struct MyStruct;
impl MyTrait for MyStruct {
//实现trait
fn method1(&self) {
println!("方法1");
}
fn method2(&self, value: u32) -> u32 {
println!("方法2和参数:{}", value);
value * 2
}
}
fn main() {
let my_struct = MyStruct;
my_struct.method1();//方法1
let result = my_struct.method2(5);//方法2和参数:5
println!("结果: {}", result);//结果: 10
}
trait bounds约束
- 实现
trait
的前提是trait
是在本地crate
定义的 - 默认实现的方法可以调用
trait
中其他方法,即使这些方法没有默认实现
trait MyTrait {
fn method1(&self) {//method1实现了trait
println!("调用了 method1");//调用了 method1
self.method2();
}
fn method2(&self);//method2没有实现trait
}
struct MyStruct;
impl MyTrait for MyStruct {
fn method2(&self) {
println!("调用了 method2");//调用了 method2
}
}
fn main() {
let my_struct = MyStruct;
my_struct.method1();
}
trait
中作为参数
trait MyTrait {
fn method(&self);
}
struct MyStruct;
impl MyTrait for MyStruct {
fn method(&self) {
println!(" 方法");
}
}
// 使用 `impl trait` 方法
fn perform_action_with_impl_trait(item: impl MyTrait) {
item.method();
}
// 使用 `trait bound` 方法
fn perform_action_with_trait_bound<T: MyTrait>(item: T) {
item.method();
}
fn main() {
let my_struct = MyStruct;
// 使用 `impl trait` 方法调用函数
// perform_action_with_impl_trait(my_struct);
// 使用 `trait bound` 方法调用函数
perform_action_with_trait_bound(my_struct);
}
where
子句指定多个trait bound
//声明trait
trait Display {
fn display(&self);
}
trait Debug {
fn debug(&self);
}
trait Clone {
fn clone(&self);
}
//声明结构体
struct MyStruct1;
struct MyStruct2;
//实现trait方法
impl Display for MyStruct1 {
fn display(&self) {
println!("Displaying Trait");
}
}
impl Debug for MyStruct1 {
fn debug(&self) {
println!("Debugging Trait");
}
}
impl Clone for MyStruct2 {
fn clone(&self) {
println!("Clone Trait");
}
}
impl Debug for MyStruct2 {
fn debug(&self) {
println!("Clone Trait");
}
}
//指定多个trait
fn perform_action<T, U>(item1: T, item2: U)
where
T: Display + Debug,
U: Clone + Debug,
{
item1.display(); // Displaying Trait
item1.debug(); // Debugging Trait
item2.clone(); // Clone Trait
}
fn main() {
let my_struct1 = MyStruct1;
let my_struct2 = MyStruct2;
perform_action(my_struct1, my_struct2);
}
实现trait
作为返回类型
trait Shape {
fn area(&self) -> f64;
}
struct Rectangle {
width: f64,
height: f64,
}
impl Shape for Rectangle {
fn area(&self) -> f64 {
self.width * self.height //返回矩形面积
}
}
struct Circle {
radius: f64,
}
impl Shape for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * self.radius.powi(2) //返回圆形面积
}
}
fn create_shape(is_rectangle: bool) -> Box<dyn Shape> {
if is_rectangle {
Box::new(Rectangle {
width: 5.0,
height: 3.0,
})
} else {
Box::new(Circle { radius: 2.0 })
}
}
fn main() {
let rectangle = create_shape(true);
let circle = create_shape(false);
println!("矩形面积: {}", rectangle.area());//矩形面积: 15
println!("圆形面积: {}", circle.area());//圆形面积: 12.566370614359172
}
有条件的实现方法
trait Printable {
fn print(&self);
}
struct Number {
value: i32,
}
impl<T> Printable for T
where
T: std::fmt::Display,
{
fn print(&self) {
println!("Value: {}", self);//Value: Hello, world!
}
}
fn main() {
let number = Number { value: 42 };
// number.print();
let string = "Hello, world!";
string.print();//只有实现了std::fmt::Display trait的类型才能实现
}
trait
定义关联类型,实现该trait时被具体化
struct MyIterator {
data: Vec<i32>,
index: usize,
}
impl Iterator for MyIterator {
type Item = i32;//具体化
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.data.len() {
let item = self.data[self.index];
self.index += 1;
Some(item)
} else {
None
}
}
}
fn main() {
let my_iterator = MyIterator {
data: vec![1, 2, 3, 4, 5],
index: 0,
};
for item in my_iterator {
println!("元素: {}", item);//元素: 1元素: 2元素: 3元素: 4元素: 5
}
}
balanket implementations 覆盖实现
为满足trait bound
的所有类型实现trait
impl<T: Display> ToString for T {//对所有实现两Display的trait实现tostring trait
// --snip--
}