Rust面向对象:简单总结impl ... for ... 结构在 Rust 中两种主要用途

impl ... for ... 结构在 Rust 中有两种主要用途:

  1. 为类型定义方法

    • 语法:impl 类型名 { ... }
    • 用于为结构体、枚举等类型定义关联函数和实例方法
    • 示例中为 Rectangle 结构体定义了 new(关联函数)、areascale(实例方法)
  2. 为类型实现特质

    • 语法:impl 特质名 for 类型名 { ... }
    • 用于为类型实现特定的特质,实现接口定义的方法
    • 示例中为 Circle 实现了 Shape 特质,为 i32Stringbool 实现了 Printable 特质

关键概念解析

  • 关联函数 :在 impl 块中定义的没有 self 参数的函数,通过 类型名::函数名() 调用(如 Rectangle::new()

  • 实例方法 :在 impl 块中定义的带有 self 参数的函数,通过实例调用(如 rect.area()

    • &self:不可变引用,用于只读操作
    • &mut self:可变引用,用于修改实例
    • self:获取所有权,调用后原实例不再可用
  • 特质实现 :通过 impl Trait for Type 为类型实现特质,必须实现特质中所有的方法

    • 一个类型可以实现多个特质
    • 一个特质可以被多个类型实现
    • 这种机制实现了 Rust 中的多态性
  • 新类型模式 :由于 Rust 不允许直接为基本类型(如 i32f64)实现方法或特质,我们可以创建一个简单的结构体来包装基本类型(如示例中的 FahrenheitCelsius),然后为这个新类型实现方法

impl ... for ... 是 Rust 中实现面向对象特性的核心机制,它允许我们将数据和行为关联起来,同时保持代码的灵活性和可扩展性。通过为不同类型实现相同的特质,我们可以写出通用的代码,实现多态行为。

具体代码参见

rust 复制代码
// 1. 为结构体实现方法
struct Rectangle {
    width: u32,
    height: u32,
}

// 为Rectangle结构体实现方法
impl Rectangle {
    // 关联函数(类似静态方法)
    fn new(width: u32, height: u32) -> Self {
        Rectangle { width, height }
    }
    
    // 实例方法
    fn area(&self) -> u32 {
        self.width * self.height
    }
    
    // 修改自身的方法
    fn scale(&mut self, factor: u32) {
        self.width *= factor;
        self.height *= factor;
    }
}

// 2. 为枚举实现方法
enum Calculator {
    Add,
    Subtract,
    Multiply,
    Divide,
}

impl Calculator {
    // 实现计算功能的方法
    fn calculate(&self, a: i32, b: i32) -> Option<i32> {
        match self {
            Calculator::Add => Some(a + b),
            Calculator::Subtract => Some(a - b),
            Calculator::Multiply => Some(a * b),
            Calculator::Divide => {
                if b == 0 {
                    None
                } else {
                    Some(a / b)
                }
            }
        }
    }
    
    // 返回操作符字符串
    fn symbol(&self) -> &str {
        match self {
            Calculator::Add => "+",
            Calculator::Subtract => "-",
            Calculator::Multiply => "*",
            Calculator::Divide => "/",
        }
    }
}

// 3. 为类型实现特质(trait)
// 定义一个特质
trait Shape {
    fn area(&self) -> f64;
    fn perimeter(&self) -> f64;
    fn name(&self) -> &str;
}

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

// 为Circle实现Shape特质
impl Shape for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }
    
    fn perimeter(&self) -> f64 {
        2.0 * std::f64::consts::PI * self.radius
    }
    
    fn name(&self) -> &str {
        "Circle"
    }
}

// 4. 为基本类型实现方法(通过新类型模式)
// Rust不允许直接为基本类型实现方法,需要使用新类型包装
struct Fahrenheit(f64);
struct Celsius(f64);

impl Fahrenheit {
    fn to_celsius(&self) -> Celsius {
        Celsius((self.0 - 32.0) * 5.0 / 9.0)
    }
}

impl Celsius {
    fn to_fahrenheit(&self) -> Fahrenheit {
        Fahrenheit(self.0 * 9.0 / 5.0 + 32.0)
    }
}

// 5. 为多个类型实现同一特质
trait Printable {
    fn print(&self);
}

impl Printable for i32 {
    fn print(&self) {
        println!("Integer value: {}", self);
    }
}

impl Printable for String {
    fn print(&self) {
        println!("String value: '{}'", self);
    }
}

impl Printable for bool {
    fn print(&self) {
        println!("Boolean value: {}", self);
    }
}

fn main() {
    // 演示结构体方法
    let mut rect = Rectangle::new(10, 20);
    println!("Rectangle area: {}", rect.area());
    rect.scale(2);
    println!("Scaled rectangle area: {}", rect.area());
    
    // 演示枚举方法
    let operations = [
        Calculator::Add,
        Calculator::Subtract,
        Calculator::Multiply,
        Calculator::Divide,
    ];
    
    let a = 10;
    let b = 5;
    for op in operations.iter() {
        match op.calculate(a, b) {
            Some(result) => println!("{} {} {} = {}", a, op.symbol(), b, result),
            None => println!("{} {} {} = Error", a, op.symbol(), b),
        }
    }
    
    // 演示特质实现
    let circle = Circle { radius: 5.0 };
    println!("\n{} - Area: {:.2}, Perimeter: {:.2}", 
             circle.name(), circle.area(), circle.perimeter());
    
    // 演示新类型模式
    let temp_f = Fahrenheit(98.6);
    let temp_c = temp_f.to_celsius();
    println!("\n98.6°F = {:.1}°C", temp_c.0);
    
    // 演示多类型特质实现
    println!("\nPrintable values:");
    42.print();
    "Hello".to_string().print();
    true.print();
}
相关推荐
招风的黑耳36 分钟前
我用SpringBoot撸了一个智慧水务监控平台
java·spring boot·后端
Miss_Chenzr40 分钟前
Springboot优卖电商系统s7zmj(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
期待のcode42 分钟前
Springboot核心构建插件
java·spring boot·后端
2501_921649491 小时前
如何获取美股实时行情:Python 量化交易指南
开发语言·后端·python·websocket·金融
serendipity_hky2 小时前
【SpringCloud | 第5篇】Seata分布式事务
分布式·后端·spring·spring cloud·seata·openfeign
五阿哥永琪2 小时前
Spring Boot 中自定义线程池的正确使用姿势:定义、注入与最佳实践
spring boot·后端·python
Victor3562 小时前
Netty(16)Netty的零拷贝机制是什么?它如何提高性能?
后端
Victor3562 小时前
Netty(15)Netty的线程模型是什么?它有哪些线程池类型?
后端
canonical_entropy3 小时前
Nop入门:增加DSL模型解析器
spring boot·后端·架构