13 rust基础-trait

Rust 的 trait 它定义了一组方法,允许不同类型实现这些方法,提供行为的抽象。用于泛型约束、共享行为和多态,类似于一种父接口(默认实现、多重继承、关联类型和泛型),trait还可以为已有stract进行扩展方法使用。
在 Rust 中,trait(特征)是一种定义共享行为的机制,类似于其他语言中的接口或抽象基类。它允许我们为不同类型定义一组必须实现的方法,从而实现多态性和代码复用。
既可以看作一种接口,也可以用于为现有类型添加方法。

举例:

// 定义一个Shape trait,它有一个计算面积的方法和一个关联类型来表示形状的单位
trait Shape {
    type Unit;  // 关联类型

    fn area(&self) -> f64;  // 计算面积
    fn unit(&self) -> Self::Unit;  // 返回形状单位
}

// 定义一个Circle结构体
struct Circle {
    radius: f64,
}

impl Shape for Circle {
    type Unit = String;  // 这里也使用String作为单位类型

    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }

    fn unit(&self) -> Self::Unit {
        "m²".to_string()  // 圆的单位是“m²”
    }
}

// 定义一个Rectangle结构体
struct Rectangle {
    width: f64,
    height: f64,
}

impl Shape for Rectangle {
    type Unit = String;  // 这里也使用String作为单位类型

    fn area(&self) -> f64 {
        self.width * self.height
    }

    fn unit(&self) -> Self::Unit {
        "m²".to_string()  // 长方形的单位是“m²”
    }
}

// 使用泛型约束
fn print_area<T: Shape<Unit = String>>(shape: T) {
    println!("Area: {} {}", shape.area(), shape.unit());
}

// 展示多态:通过Shape trait来使用不同的形状
fn main() {
    let circle = Circle { radius: 5.0 };
    let rectangle = Rectangle { width: 4.0, height: 6.0 };

    print_area(circle);     // 输出: Area: 78.53981633974483 m²
    print_area(rectangle);  // 输出: Area: 24 m²
}

trait 默认实现

trait 允许为其方法提供默认实现,这样在具体类型实现该 trait 时,可以选择使用默认实现或提供自定义实现。例如:

trait Greet {
    fn say_hello(&self) {
        println!("Hello!");
    }
}

struct Person;

impl Greet for Person {
    // 使用默认实现
}

struct Robot;

impl Greet for Robot {
    fn say_hello(&self) {
        println!("Beep beep!");
    }
}

在这个示例中,Person 类型使用了 Greet trait 的默认实现,而 Robot 类型提供了自定义的 say_hello 方法。

trait 与泛型

在函数或类型中使用泛型时,可以对泛型参数施加 trait 约束,确保泛型类型实现了特定的行为。例如:

fn greet<T: Greet>(entity: T) {
    entity.say_hello();
}

这里,函数 greet 接受一个泛型参数 T,但要求 T 实现了 Greet trait。这样,传入的任何类型只要实现了 Greet,都可以调用 greet 函数。

trait 对象

在某些情况下,我们需要在运行时处理不同类型的值,但这些类型都实现了相同的 trait。此时,可以使用 trait 对象。trait 对象使用动态分发,允许在运行时确定调用哪个方法实现。定义 trait 对象时,需要使用 dyn 关键字:

fn greet(entity: &dyn Greet) {
    entity.say_hello();
}

trait SomeTrait {
fn some_function(&self) -> bool {
true
}
}

trait OtherTrait {
fn other_function(&self) -> bool {
true
}
}

多trait 统一泛型

struct SomeStruct;
impl SomeTrait for SomeStruct {}
impl OtherTrait for SomeStruct {}

struct OtherStruct;
impl SomeTrait for OtherStruct {}
impl OtherTrait for OtherStruct {}

// TODO: Fix the compiler error by only changing the signature of this function.
fn some_func<T>(item: T) -> bool 
where
    T: SomeStruct + OtherStruct
{
    item.some_function() && item.other_function()
}
posted @ 2025-02-24 11:58  代码世界faq  阅读(44)  评论(0)    收藏  举报