Rust简明教程第五章-Trait 特质

观看B站软件工艺师杨旭的rust教程学习记录,有删减有补充

Trait 特质

  • trait:共同行为,与其他类型共享的功能
  • trait bounds(约束):将泛型类型参数指定为实现了指定行为的类型
  • trait只有方法签名没有具体实现
  • 实现trait类型必须实现其方法
rust 复制代码
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中其他方法,即使这些方法没有默认实现
rust 复制代码
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中作为参数

rust 复制代码
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

rust 复制代码
//声明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作为返回类型

rust 复制代码
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
}

有条件的实现方法

rust 复制代码
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时被具体化

rust 复制代码
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

rust 复制代码
impl<T: Display> ToString for T {//对所有实现两Display的trait实现tostring trait
    // --snip--
}
相关推荐
x秀x5 分钟前
sam3新手使用教程
开发语言·python
Java后端的Ai之路6 分钟前
大模型LLM评估完全指南
开发语言·人工智能·python·llm·评估
盖伦发发8 分钟前
Redis 核心教学: 数据结构, 缓存设计, 分布式锁
java·redis·后端·软件工程
卷毛的技术笔记9 分钟前
RocketMQ事务消息:我把分布式事务这层窗户纸捅破了
java·分布式·后端·java-rocketmq
Brilliantwxx18 分钟前
【STM32】 从HAL库源码深度解析I2C(源码解析+面试题)
开发语言·stm32·单片机·嵌入式硬件·架构
铁皮饭盒22 分钟前
网页端, 40mb离线模型, 自动抠图, 不用 Python,不用服务器,不用 API Key, 不用显卡
前端·javascript·后端
小白学大数据30 分钟前
Python 小工具实战:用问财接口搭建金融数据采集器
开发语言·人工智能·python
泡海椒32 分钟前
jquick-pdf 核心原理解析:基于 HTML 模板动态渲染 PDF 的实现逻辑
java·开发语言·pdf
IT_陈寒35 分钟前
Redis并发写入踩坑记录:别让超时设置坑了你
前端·人工智能·后端
Bs_MoneyMagnet41 分钟前
基于springboot+vue的图书馆预约系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·毕业设计·图书管理系统·计算机毕业设计