在这里插入图片描述

第16章 面向对象编程特性

尽管Rust不是一门纯粹的面向对象语言,但它提供了强大的工具和模式来支持面向对象编程范式。Rust通过结构体、枚举、trait和模式匹配等特性,以独特的方式实现了封装、继承和多态等面向对象概念。本章将深入探讨Rust中的面向对象编程特性,包括如何使用trait对象实现多态、如何在Rust中实现常见的设计模式,以及如何在面向对象编程和Rust的固有风格之间找到平衡。

16.1 面向对象语言特性

封装与信息隐藏

封装是面向对象编程的基石,它允许隐藏对象的内部实现细节,只暴露必要的接口。Rust通过模块系统和可见性修饰符提供了强大的封装支持。

基本封装模式
pub struct BankAccount {
    account_number: String,
    balance: f64,
    is_active: bool,
    transaction_history: Vec<Transaction>,
}

impl BankAccount {
    // 构造函数
    pub fn new(account_number: String, initial_balance: f64) -> Self {
        BankAccount {
            account_number,
            balance: initial_balance,
            is_active: true,
            transaction_history: Vec::new(),
        }
    }

    // 公开的getter方法
    pub fn account_number(&self) -> &str {
        &self.account_number
    }

    pub fn balance(&self) -> f64 {
        self.balance
    }

    pub fn is_active(&self) -> bool {
        self.is_active
    }

    // 受控的修改方法
    pub fn deposit(&mut self, amount: f64) -> Result<(), String> {
        if !self.is_active {
            return Err("账户已冻结".to_string());
        }
        if amount <= 0.0 {
            return Err("存款金额必须为正数".to_string());
        }

        self.balance += amount;
        self.transaction_history.push(Transaction::deposit(amount));
        Ok(())
    }

    pub fn withdraw(&mut self, amount: f64) -> Result<f64, String> {
        if !self.is_active {
            return Err("账户已冻结".to_string());
        }
        if amount <= 0.0 {
            return Err("取款金额必须为正数".to_string());
        }
        if amount > self.balance {
            return Err("余额不足".to_string());
        }

        self.balance -= amount;
        self.transaction_history.push(Transaction::withdrawal(amount));
        Ok(amount)
    }

    // 内部实现细节
    fn add_interest(&mut self, rate: f64) {
        let interest = self.balance * rate;
        self.balance += interest;
        self.transaction_history.push(Transaction::interest(interest));
    }

    // 提供有限的交易历史访问
    pub fn recent_transactions(&self, count: usize) -> Vec<&Transaction> {
        self.transaction_history
            .iter()
            .rev()
            .take(count)
            .collect()
    }
}

#[derive(Debug, Clone)]
struct Transaction {
    kind: TransactionType,
    amount: f64,
    timestamp: std::time::SystemTime,
}

#[derive(Debug, Clone)]
enum TransactionType {
    Deposit,
    Withdrawal,
    Interest,
    Transfer,
}

impl Transaction {
    fn deposit(amount: f64) -> Self {
        Transaction {
            kind: TransactionType::Deposit,
            amount,
            timestamp: std::time::SystemTime::now(),
        }
    }

    fn withdrawal(amount: f64) -> Self {
        Transaction {
            kind: TransactionType::Withdrawal,
            amount,
            timestamp: std::time::SystemTime::now(),
        }
    }

    fn interest(amount: f64) -> Self {
        Transaction {
            kind: TransactionType::Interest,
            amount,
            timestamp: std::time::SystemTime::now(),
        }
    }
}

fn encapsulation_demo() {
    println!("=== 封装与信息隐藏演示 ===");
    
    let mut account = BankAccount::new("123456789".to_string(), 1000.0);
    
    println!("账户号码: {}", account.account_number());
    println!("初始余额: {:.2}", account.balance());
    println!("账户状态: {}", if account.is_active() { "活跃" } else { "冻结" });
    
    // 存款操作
    match account.deposit(500.0) {
        Ok(()) => println!("存款成功"),
        Err(e) => println!("存款失败: {}", e),
    }
    
    // 取款操作
    match account.withdraw(200.0) {
        Ok(amount) => println!("取款成功: {:.2}", amount),
        Err(e) => println!("取款失败: {}", e),
    }
    
    // 尝试非法操作
    match account.withdraw(-100.0) {
        Ok(_) => println!("这不应该发生"),
        Err(e) => println!("预期中的错误: {}", e),
    }
    
    println!("最终余额: {:.2}", account.balance());
    
    // 查看最近交易
    println!("最近交易:");
    for tx in account.recent_transactions(3) {
        println!("  {:?} - {:.2}", tx.kind, tx.amount);
    }
    
    // 无法直接访问私有字段
    // println!("直接访问: {}", account.balance); // 编译错误
}

组合优于继承

Rust不支持传统的类继承,而是鼓励使用组合和trait来实现代码复用和多态。

组合模式示例
// 使用组合构建复杂对象
struct Address {
    street: String,
    city: String,
    postal_code: String,
    country: String,
}

impl Address {
    fn new(street: &str, city: &str, postal_code: &str, country: &str) -> Self {
        Address {
            street: street.to_string(),
            city: city.to_string(),
            postal_code: postal_code.to_string(),
            country: country.to_string(),
        }
    }
    
    fn format(&self) -> String {
        format!(
            "{}, {}, {} {}",
            self.street, self.city, self.postal_code, self.country
        )
    }
}

struct ContactInfo {
    email: String,
    phone: String,
    address: Address, // 组合:ContactInfo包含Address
}

impl ContactInfo {
    fn new(email: &str, phone: &str, address: Address) -> Self {
        ContactInfo {
            email: email.to_string(),
            phone: phone.to_string(),
            address,
        }
    }
    
    fn display(&self) {
        println!("邮箱: {}", self.email);
        println!("电话: {}", self.phone);
        println!("地址: {}", self.address.format());
    }
}

struct Customer {
    id: u32,
    name: String,
    contact: ContactInfo, // 组合:Customer包含ContactInfo
    loyalty_points: u32,
}

impl Customer {
    fn new(id: u32, name: &str, contact: ContactInfo) -> Self {
        Customer {
            id,
            name: name.to_string(),
            contact,
            loyalty_points: 0,
        }
    }
    
    fn add_loyalty_points(&mut self, points: u32) {
        self.loyalty_points += points;
        println!("{} 获得 {} 积分,总计: {}", self.name, points, self.loyalty_points);
    }
    
    fn display_profile(&self) {
        println!("客户 ID: {}", self.id);
        println!("姓名: {}", self.name);
        println!("积分: {}", self.loyalty_points);
        self.contact.display();
    }
}

fn composition_demo() {
    println!("=== 组合优于继承演示 ===");
    
    let address = Address::new(
        "123 Rust Street",
        "Systems City",
        "10001",
        "Programland"
    );
    
    let contact = ContactInfo::new(
        "alice@example.com",
        "+1-555-0123",
        address
    );
    
    let mut customer = Customer::new(1, "Alice", contact);
    
    customer.display_profile();
    println!();
    
    customer.add_loyalty_points(100);
    customer.add_loyalty_points(50);
    
    println!("\n完整的客户信息:");
    customer.display_profile();
}

方法语法与关联函数

Rust使用impl块为结构体和枚举定义方法,提供了面向对象风格的方法调用语法。

struct Rectangle {
    width: f64,
    height: f64,
}

impl Rectangle {
    // 关联函数(类似于静态方法)
    fn new(width: f64, height: f64) -> Self {
        Rectangle { width, height }
    }
    
    fn square(size: f64) -> Self {
        Rectangle {
            width: size,
            height: size,
        }
    }
    
    // 实例方法
    fn area(&self) -> f64 {
        self.width * self.height
    }
    
    fn perimeter(&self) -> f64 {
        2.0 * (self.width + self.height)
    }
    
    fn can_contain(&self, other: &Rectangle) -> bool {
        self.width >= other.width && self.height >= other.height
    }
    
    // 可变方法
    fn scale(&mut self, factor: f64) {
        self.width *= factor;
        self.height *= factor;
    }
    
    // 获取所有权的方法
    fn combine(self, other: Rectangle) -> Rectangle {
        Rectangle {
            width: self.width + other.width,
            height: self.height.max(other.height),
        }
    }
}

// 为同一类型实现多个impl块
impl Rectangle {
    fn aspect_ratio(&self) -> f64 {
        self.width / self.height
    }
    
    fn is_square(&self) -> bool {
        (self.width - self.height).abs() < f64::EPSILON
    }
}

fn method_syntax_demo() {
    println!("=== 方法语法演示 ===");
    
    let rect1 = Rectangle::new(10.0, 20.0);
    let rect2 = Rectangle::square(15.0);
    
    println!("矩形1 - 面积: {:.2}, 周长: {:.2}", rect1.area(), rect1.perimeter());
    println!("矩形2 - 面积: {:.2}, 周长: {:.2}", rect2.area(), rect2.perimeter());
    println!("矩形1能包含矩形2: {}", rect1.can_contain(&rect2));
    println!("矩形2是正方形: {}", rect2.is_square());
    println!("矩形1宽高比: {:.2}", rect1.aspect_ratio());
    
    let mut scalable_rect = Rectangle::new(5.0, 10.0);
    println!("缩放前: {}x{}", scalable_rect.width, scalable_rect.height);
    
    scalable_rect.scale(2.0);
    println!("缩放后: {}x{}", scalable_rect.width, scalable_rect.height);
    
    let combined = rect1.combine(rect2);
    println!("合并后的矩形: {}x{}", combined.width, combined.height);
}

16.2 使用trait对象存储不同类型值

Trait对象基础

Trait对象允许我们在运行时处理多种类型,是实现多态的重要手段。它们使用动态分发,在牺牲少量性能的同时提供了极大的灵活性。

基本Trait对象使用
trait Drawable {
    fn draw(&self);
    fn area(&self) -> f64;
    fn description(&self) -> String {
        "一个可绘制对象".to_string()
    }
}

struct Circle {
    radius: f64,
    center: (f64, f64),
}

impl Drawable for Circle {
    fn draw(&self) {
        println!("绘制圆形: 半径={}, 中心点=({}, {})", 
                 self.radius, self.center.0, self.center.1);
    }
    
    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }
    
    fn description(&self) -> String {
        format!("圆形 (半径: {})", self.radius)
    }
}

struct Rectangle {
    width: f64,
    height: f64,
    position: (f64, f64),
}

impl Drawable for Rectangle {
    fn draw(&self) {
        println!("绘制矩形: {}x{}, 位置=({}, {})", 
                 self.width, self.height, self.position.0, self.position.1);
    }
    
    fn area(&self) -> f64 {
        self.width * self.height
    }
    
    fn description(&self) -> String {
        format!("矩形 ({}x{})", self.width, self.height)
    }
}

struct Triangle {
    base: f64,
    height: f64,
    vertices: [(f64, f64); 3],
}

impl Drawable for Triangle {
    fn draw(&self) {
        println!("绘制三角形: 底边={}, 高={}", self.base, self.height);
    }
    
    fn area(&self) -> f64 {
        0.5 * self.base * self.height
    }
    
    fn description(&self) -> String {
        format!("三角形 (底: {}, 高: {})", self.base, self.height)
    }
}

fn trait_objects_basics() {
    println!("=== Trait对象基础 ===");
    
    // 创建不同类型的对象
    let circle = Circle { radius: 5.0, center: (10.0, 10.0) };
    let rectangle = Rectangle { width: 8.0, height: 6.0, position: (20.0, 20.0) };
    let triangle = Triangle { base: 10.0, height: 7.0, vertices: [(0.0, 0.0), (10.0, 0.0), (5.0, 7.0)] };
    
    // 使用trait对象存储不同类型
    let shapes: Vec<Box<dyn Drawable>> = vec![
        Box::new(circle),
        Box::new(rectangle),
        Box::new(triangle),
    ];
    
    // 统一处理不同类型的对象
    for shape in shapes {
        println!("{}", shape.description());
        shape.draw();
        println!("面积: {:.2}", shape.area());
        println!("---");
    }
}

高级Trait对象模式

Trait对象可以用于构建复杂的多态系统,如插件架构、GUI框架等。

// 更复杂的trait对象示例:支付处理系统
trait PaymentProcessor {
    fn process_payment(&self, amount: f64) -> Result<String, String>;
    fn refund(&self, transaction_id: &str) -> Result<String, String>;
    fn get_processor_name(&self) -> String;
    fn supports_currency(&self, currency: &str) -> bool;
}

struct CreditCardProcessor {
    api_key: String,
    supported_currencies: Vec<String>,
}

impl CreditCardProcessor {
    fn new(api_key: &str) -> Self {
        CreditCardProcessor {
            api_key: api_key.to_string(),
            supported_currencies: vec!["USD".to_string(), "EUR".to_string(), "GBP".to_string()],
        }
    }
}

impl PaymentProcessor for CreditCardProcessor {
    fn process_payment(&self, amount: f64) -> Result<String, String> {
        if amount <= 0.0 {
            return Err("金额必须大于0".to_string());
        }
        
        // 模拟API调用
        let transaction_id = format!("CC_{}_{}", self.api_key, rand::random::<u32>());
        Ok(format!("信用卡支付成功,交易ID: {}", transaction_id))
    }
    
    fn refund(&self, transaction_id: &str) -> Result<String, String> {
        if !transaction_id.starts_with("CC_") {
            return Err("无效的信用卡交易ID".to_string());
        }
        
        Ok(format!("信用卡退款成功,交易ID: {}", transaction_id))
    }
    
    fn get_processor_name(&self) -> String {
        "信用卡支付处理器".to_string()
    }
    
    fn supports_currency(&self, currency: &str) -> bool {
        self.supported_currencies.contains(&currency.to_string())
    }
}

struct PayPalProcessor {
    email: String,
    sandbox: bool,
}

impl PayPalProcessor {
    fn new(email: &str, sandbox: bool) -> Self {
        PayPalProcessor {
            email: email.to_string(),
            sandbox,
        }
    }
}

impl PaymentProcessor for PayPalProcessor {
    fn process_payment(&self, amount: f64) -> Result<String, String> {
        if amount < 1.0 {
            return Err("PayPal支付最低金额为1.0".to_string());
        }
        
        let environment = if self.sandbox { "沙盒" } else { "生产" };
        let transaction_id = format!("PP_{}_{}", self.email, rand::random::<u32>());
        
        Ok(format!("PayPal支付成功 ({}), 交易ID: {}", environment, transaction_id))
    }
    
    fn refund(&self, transaction_id: &str) -> Result<String, String> {
        if !transaction_id.starts_with("PP_") {
            return Err("无效的PayPal交易ID".to_string());
        }
        
        Ok(format!("PayPal退款成功,交易ID: {}", transaction_id))
    }
    
    fn get_processor_name(&self) -> String {
        "PayPal支付处理器".to_string()
    }
    
    fn supports_currency(&self, currency: &str) -> bool {
        // PayPal支持更多货币
        matches!(currency, "USD" | "EUR" | "GBP" | "CAD" | "AUD" | "JPY")
    }
}

struct CryptoProcessor {
    wallet_address: String,
    network: String,
}

impl CryptoProcessor {
    fn new(wallet_address: &str, network: &str) -> Self {
        CryptoProcessor {
            wallet_address: wallet_address.to_string(),
            network: network.to_string(),
        }
    }
}

impl PaymentProcessor for CryptoProcessor {
    fn process_payment(&self, amount: f64) -> Result<String, String> {
        if amount < 0.001 {
            return Err("加密货币支付最低金额为0.001".to_string());
        }
        
        let transaction_id = format!("CRYPTO_{}_{}", self.wallet_address, rand::random::<u32>());
        Ok(format!("加密货币支付成功 ({}), 交易ID: {}", self.network, transaction_id))
    }
    
    fn refund(&self, _transaction_id: &str) -> Result<String, String> {
        Err("加密货币支付不支持退款".to_string())
    }
    
    fn get_processor_name(&self) -> String {
        format!("加密货币处理器 ({})", self.network)
    }
    
    fn supports_currency(&self, currency: &str) -> bool {
        matches!(currency, "BTC" | "ETH" | "USDT")
    }
}

// 支付处理管理器
struct PaymentManager {
    processors: Vec<Box<dyn PaymentProcessor>>,
}

impl PaymentManager {
    fn new() -> Self {
        PaymentManager {
            processors: Vec::new(),
        }
    }
    
    fn add_processor(&mut self, processor: Box<dyn PaymentProcessor>) {
        self.processors.push(processor);
    }
    
    fn process_with_currency(&self, amount: f64, currency: &str) -> Result<String, String> {
        for processor in &self.processors {
            if processor.supports_currency(currency) {
                println!("使用: {}", processor.get_processor_name());
                return processor.process_payment(amount);
            }
        }
        
        Err(format!("没有找到支持货币 {} 的支付处理器", currency))
    }
    
    fn list_processors(&self) {
        println!("可用的支付处理器:");
        for (i, processor) in self.processors.iter().enumerate() {
            println!("  {}. {}", i + 1, processor.get_processor_name());
        }
    }
}

fn advanced_trait_objects_demo() {
    println!("=== 高级Trait对象演示 ===");
    
    let mut payment_manager = PaymentManager::new();
    
    // 注册不同的支付处理器
    payment_manager.add_processor(Box::new(CreditCardProcessor::new("sk_test_123")));
    payment_manager.add_processor(Box::new(PayPalProcessor::new("merchant@example.com", true)));
    payment_manager.add_processor(Box::new(CryptoProcessor::new("0x742d35Cc...", "Ethereum")));
    
    payment_manager.list_processors();
    println!();
    
    // 测试不同货币的支付
    let test_cases = vec![
        (100.0, "USD"),
        (50.0, "EUR"),
        (0.1, "BTC"),
        (25.0, "CAD"),
        (0.0001, "ETH"), // 这个会失败,金额太小
    ];
    
    for (amount, currency) in test_cases {
        println!("尝试支付: {} {}", amount, currency);
        match payment_manager.process_with_currency(amount, currency) {
            Ok(result) => println!("成功: {}", result),
            Err(error) => println!("失败: {}", error),
        }
        println!("---");
    }
}

Trait对象的限制与解决方案

Trait对象有一些限制,了解这些限制及其解决方案对于有效使用它们至关重要。

fn trait_object_limitations() {
    println!("=== Trait对象的限制与解决方案 ===");
    
    // 限制1: Trait对象不能返回Self
    trait Cloneable: Clone {
        fn clone_me(&self) -> Self;
    }
    
    // 下面的代码无法编译,因为trait对象不能使用Self
    // let objects: Vec<Box<dyn Cloneable>> = vec![];
    
    // 解决方案: 使用Box<dyn Trait>
    trait CloneableTrait {
        fn clone_box(&self) -> Box<dyn CloneableTrait>;
    }
    
    impl<T> CloneableTrait for T
    where
        T: Clone + 'static,
    {
        fn clone_box(&self) -> Box<dyn CloneableTrait> {
            Box::new(self.clone())
        }
    }
    
    // 限制2: 只能使用对象安全的trait
    // 对象安全的trait不能有泛型方法或返回Self的方法
    
    // 解决方案: 将泛型方法拆分为不同的trait
    trait GenericProcessor {
        fn process<T: serde::Serialize>(&self, data: T) -> Result<String, String>;
    }
    
    // 这个trait不是对象安全的,因为有泛型方法
    // let processors: Vec<Box<dyn GenericProcessor>> = vec![]; // 编译错误
    
    trait ObjectSafeProcessor {
        fn process_json(&self, json_data: &str) -> Result<String, String>;
    }
    
    // 这个trait是对象安全的
    let _processors: Vec<Box<dyn ObjectSafeProcessor>> = vec![];
    
    println!("了解trait对象的限制很重要!");
}

16.3 面向对象设计模式实现

工厂模式

工厂模式提供了一种创建对象的方式,而无需向客户端暴露实例化逻辑。

// 工厂模式示例:文档处理系统
trait Document {
    fn open(&self);
    fn save(&self);
    fn close(&self);
    fn get_type(&self) -> String;
}

struct TextDocument {
    content: String,
    file_path: String,
}

impl TextDocument {
    fn new(content: &str, file_path: &str) -> Self {
        TextDocument {
            content: content.to_string(),
            file_path: file_path.to_string(),
        }
    }
}

impl Document for TextDocument {
    fn open(&self) {
        println!("打开文本文档: {}", self.file_path);
        println!("内容预览: {}...", &self.content[..self.content.len().min(50)]);
    }
    
    fn save(&self) {
        println!("保存文本文档到: {}", self.file_path);
    }
    
    fn close(&self) {
        println!("关闭文本文档: {}", self.file_path);
    }
    
    fn get_type(&self) -> String {
        "text/plain".to_string()
    }
}

struct PdfDocument {
    file_path: String,
    page_count: u32,
}

impl PdfDocument {
    fn new(file_path: &str, page_count: u32) -> Self {
        PdfDocument {
            file_path: file_path.to_string(),
            page_count,
        }
    }
}

impl Document for PdfDocument {
    fn open(&self) {
        println!("打开PDF文档: {}", self.file_path);
        println!("页数: {}", self.page_count);
    }
    
    fn save(&self) {
        println!("保存PDF文档到: {}", self.file_path);
    }
    
    fn close(&self) {
        println!("关闭PDF文档: {}", self.file_path);
    }
    
    fn get_type(&self) -> String {
        "application/pdf".to_string()
    }
}

struct SpreadsheetDocument {
    file_path: String,
    sheet_count: u32,
}

impl SpreadsheetDocument {
    fn new(file_path: &str, sheet_count: u32) -> Self {
        SpreadsheetDocument {
            file_path: file_path.to_string(),
            sheet_count,
        }
    }
}

impl Document for SpreadsheetDocument {
    fn open(&self) {
        println!("打开电子表格: {}", self.file_path);
        println!("工作表数量: {}", self.sheet_count);
    }
    
    fn save(&self) {
        println!("保存电子表格到: {}", self.file_path);
    }
    
    fn close(&self) {
        println!("关闭电子表格: {}", self.file_path);
    }
    
    fn get_type(&self) -> String {
        "application/vnd.ms-excel".to_string()
    }
}

// 文档工厂
enum DocumentType {
    Text,
    Pdf,
    Spreadsheet,
}

struct DocumentFactory;

impl DocumentFactory {
    fn create_document(doc_type: DocumentType, file_path: &str) -> Box<dyn Document> {
        match doc_type {
            DocumentType::Text => Box::new(TextDocument::new("默认内容", file_path)),
            DocumentType::Pdf => Box::new(PdfDocument::new(file_path, 1)),
            DocumentType::Spreadsheet => Box::new(SpreadsheetDocument::new(file_path, 1)),
        }
    }
    
    fn create_document_from_extension(file_path: &str) -> Result<Box<dyn Document>, String> {
        let extension = file_path
            .rsplit('.')
            .next()
            .ok_or("无法确定文件扩展名")?;
            
        match extension.to_lowercase().as_str() {
            "txt" => Ok(Self::create_document(DocumentType::Text, file_path)),
            "pdf" => Ok(Self::create_document(DocumentType::Pdf, file_path)),
            "xlsx" | "xls" => Ok(Self::create_document(DocumentType::Spreadsheet, file_path)),
            _ => Err(format!("不支持的文件类型: .{}", extension)),
        }
    }
}

fn factory_pattern_demo() {
    println!("=== 工厂模式演示 ===");
    
    // 使用工厂创建文档
    let documents = vec![
        DocumentFactory::create_document(DocumentType::Text, "document.txt"),
        DocumentFactory::create_document(DocumentType::Pdf, "presentation.pdf"),
        DocumentFactory::create_document(DocumentType::Spreadsheet, "data.xlsx"),
    ];
    
    for doc in documents {
        println!("文档类型: {}", doc.get_type());
        doc.open();
        doc.save();
        doc.close();
        println!("---");
    }
    
    // 根据文件扩展名创建文档
    let file_paths = vec!["readme.txt", "manual.pdf", "budget.xlsx", "image.png"];
    
    for file_path in file_paths {
        println!("处理文件: {}", file_path);
        match DocumentFactory::create_document_from_extension(file_path) {
            Ok(doc) => {
                doc.open();
                doc.close();
            }
            Err(e) => println!("错误: {}", e),
        }
        println!("---");
    }
}

观察者模式

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。

use std::collections::HashMap;
use std::sync::{Arc, Mutex};

// 观察者模式示例:股票市场监控系统
type ObserverId = u64;

trait Observer {
    fn update(&self, symbol: &str, price: f64);
    fn get_id(&self) -> ObserverId;
}

trait Subject {
    fn register_observer(&mut self, observer: Arc<dyn Observer>);
    fn remove_observer(&mut self, observer_id: ObserverId);
    fn notify_observers(&self, symbol: &str, price: f64);
}

// 具体的主题:股票
struct Stock {
    symbol: String,
    price: f64,
    observers: Arc<Mutex<HashMap<ObserverId, Arc<dyn Observer>>>>,
    next_observer_id: ObserverId,
}

impl Stock {
    fn new(symbol: &str, initial_price: f64) -> Self {
        Stock {
            symbol: symbol.to_string(),
            price: initial_price,
            observers: Arc::new(Mutex::new(HashMap::new())),
            next_observer_id: 1,
        }
    }
    
    fn set_price(&mut self, new_price: f64) {
        let old_price = self.price;
        self.price = new_price;
        
        if (new_price - old_price).abs() > f64::EPSILON {
            println!("{} 价格变化: {:.2} -> {:.2}", self.symbol, old_price, new_price);
            self.notify_observers(&self.symbol, new_price);
        }
    }
    
    fn get_price(&self) -> f64 {
        self.price
    }
}

impl Subject for Stock {
    fn register_observer(&mut self, observer: Arc<dyn Observer>) {
        let observer_id = observer.get_id();
        self.observers.lock().unwrap().insert(observer_id, observer);
        self.next_observer_id += 1;
    }
    
    fn remove_observer(&mut self, observer_id: ObserverId) {
        self.observers.lock().unwrap().remove(&observer_id);
    }
    
    fn notify_observers(&self, symbol: &str, price: f64) {
        let observers = self.observers.lock().unwrap();
        for observer in observers.values() {
            observer.update(symbol, price);
        }
    }
}

// 具体的观察者:价格显示器
struct PriceDisplay {
    id: ObserverId,
    name: String,
}

impl PriceDisplay {
    fn new(name: &str) -> Self {
        static mut NEXT_ID: ObserverId = 1;
        let id = unsafe {
            let current = NEXT_ID;
            NEXT_ID += 1;
            current
        };
        
        PriceDisplay {
            id,
            name: name.to_string(),
        }
    }
}

impl Observer for PriceDisplay {
    fn update(&self, symbol: &str, price: f64) {
        println!("[{}] {}: {:.2}", self.name, symbol, price);
    }
    
    fn get_id(&self) -> ObserverId {
        self.id
    }
}

// 具体的观察者:价格警报器
struct PriceAlert {
    id: ObserverId,
    symbol: String,
    threshold: f64,
    alert_type: AlertType,
}

#[derive(PartialEq)]
enum AlertType {
    Above,
    Below,
}

impl PriceAlert {
    fn new(symbol: &str, threshold: f64, alert_type: AlertType) -> Self {
        static mut NEXT_ID: ObserverId = 1;
        let id = unsafe {
            let current = NEXT_ID;
            NEXT_ID += 1;
            current
        };
        
        PriceAlert {
            id,
            symbol: symbol.to_string(),
            threshold,
            alert_type,
        }
    }
}

impl Observer for PriceAlert {
    fn update(&self, symbol: &str, price: f64) {
        if symbol == self.symbol {
            let should_alert = match self.alert_type {
                AlertType::Above => price > self.threshold,
                AlertType::Below => price < self.threshold,
            };
            
            if should_alert {
                let direction = match self.alert_type {
                    AlertType::Above => "高于",
                    AlertType::Below => "低于",
                };
                println!("🚨 警报! {} {:.2} {} 阈值 {:.2}", symbol, price, direction, self.threshold);
            }
        }
    }
    
    fn get_id(&self) -> ObserverId {
        self.id
    }
}

fn observer_pattern_demo() {
    println!("=== 观察者模式演示 ===");
    
    let mut apple_stock = Stock::new("AAPL", 150.0);
    let mut google_stock = Stock::new("GOOGL", 2800.0);
    
    // 创建观察者
    let display1 = Arc::new(PriceDisplay::new("主显示器"));
    let display2 = Arc::new(PriceDisplay::new("移动端"));
    
    let apple_high_alert = Arc::new(PriceAlert::new("AAPL", 160.0, AlertType::Above));
    let apple_low_alert = Arc::new(PriceAlert::new("AAPL", 140.0, AlertType::Below));
    let google_alert = Arc::new(PriceAlert::new("GOOGL", 2900.0, AlertType::Above));
    
    // 注册观察者
    apple_stock.register_observer(display1.clone());
    apple_stock.register_observer(apple_high_alert.clone());
    apple_stock.register_observer(apple_low_alert.clone());
    
    google_stock.register_observer(display1.clone());
    google_stock.register_observer(display2.clone());
    google_stock.register_observer(google_alert.clone());
    
    // 模拟价格变化
    println!("模拟股票价格变化:");
    apple_stock.set_price(155.0);
    apple_stock.set_price(145.0);  // 触发低价警报
    apple_stock.set_price(165.0);  // 触发高价警报
    
    google_stock.set_price(2850.0);
    google_stock.set_price(2950.0); // 触发Google警报
    
    // 移除一个观察者
    println!("\n移除移动端显示器后的变化:");
    google_stock.remove_observer(display2.get_id());
    google_stock.set_price(3000.0);
}

策略模式

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。

// 策略模式示例:支付处理系统
trait PaymentStrategy {
    fn pay(&self, amount: f64) -> Result<String, String>;
    fn get_name(&self) -> String;
}

struct CreditCardStrategy {
    card_number: String,
    expiry_date: String,
    cvv: String,
}

impl CreditCardStrategy {
    fn new(card_number: &str, expiry_date: &str, cvv: &str) -> Self {
        CreditCardStrategy {
            card_number: card_number.to_string(),
            expiry_date: expiry_date.to_string(),
            cvv: cvv.to_string(),
        }
    }
}

impl PaymentStrategy for CreditCardStrategy {
    fn pay(&self, amount: f64) -> Result<String, String> {
        if amount <= 0.0 {
            return Err("金额必须大于0".to_string());
        }
        
        // 模拟信用卡处理
        let masked_number = &self.card_number[self.card_number.len().saturating_sub(4)..];
        Ok(format!("信用卡支付成功! 卡号: ****{} 金额: {:.2}", masked_number, amount))
    }
    
    fn get_name(&self) -> String {
        "信用卡".to_string()
    }
}

struct PayPalStrategy {
    email: String,
}

impl PayPalStrategy {
    fn new(email: &str) -> Self {
        PayPalStrategy {
            email: email.to_string(),
        }
    }
}

impl PaymentStrategy for PayPalStrategy {
    fn pay(&self, amount: f64) -> Result<String, String> {
        if amount < 1.0 {
            return Err("PayPal支付最低金额为1.0".to_string());
        }
        
        Ok(format!("PayPal支付成功! 邮箱: {} 金额: {:.2}", self.email, amount))
    }
    
    fn get_name(&self) -> String {
        "PayPal".to_string()
    }
}

struct CryptoStrategy {
    wallet_address: String,
}

impl CryptoStrategy {
    fn new(wallet_address: &str) -> Self {
        CryptoStrategy {
            wallet_address: wallet_address.to_string(),
        }
    }
}

impl PaymentStrategy for CryptoStrategy {
    fn pay(&self, amount: f64) -> Result<String, String> {
        if amount < 0.001 {
            return Err("加密货币支付最低金额为0.001".to_string());
        }
        
        let masked_address = if self.wallet_address.len() > 8 {
            format!("{}...{}", 
                    &self.wallet_address[..4], 
                    &self.wallet_address[self.wallet_address.len()-4..])
        } else {
            self.wallet_address.clone()
        };
        
        Ok(format!("加密货币支付成功! 钱包: {} 金额: {:.4}", masked_address, amount))
    }
    
    fn get_name(&self) -> String {
        "加密货币".to_string()
    }
}

// 支付上下文
struct PaymentContext {
    strategy: Box<dyn PaymentStrategy>,
}

impl PaymentContext {
    fn new(strategy: Box<dyn PaymentStrategy>) -> Self {
        PaymentContext { strategy }
    }
    
    fn set_strategy(&mut self, strategy: Box<dyn PaymentStrategy>) {
        self.strategy = strategy;
    }
    
    fn execute_payment(&self, amount: f64) -> Result<String, String> {
        println!("使用 {} 进行支付...", self.strategy.get_name());
        self.strategy.pay(amount)
    }
}

fn strategy_pattern_demo() {
    println!("=== 策略模式演示 ===");
    
    // 创建不同的支付策略
    let credit_card = CreditCardStrategy::new("4111111111111111", "12/25", "123");
    let paypal = PayPalStrategy::new("user@example.com");
    let crypto = CryptoStrategy::new("0x1a2b3c4d5e6f7g8h9i0j");
    
    let mut payment_context = PaymentContext::new(Box::new(credit_card));
    
    // 使用信用卡支付
    match payment_context.execute_payment(100.0) {
        Ok(result) => println!("结果: {}", result),
        Err(e) => println!("错误: {}", e),
    }
    
    // 切换到PayPal
    payment_context.set_strategy(Box::new(paypal));
    match payment_context.execute_payment(50.0) {
        Ok(result) => println!("结果: {}", result),
        Err(e) => println!("错误: {}", e),
    }
    
    // 切换到加密货币
    payment_context.set_strategy(Box::new(crypto));
    match payment_context.execute_payment(0.1) {
        Ok(result) => println!("结果: {}", result),
        Err(e) => println!("错误: {}", e),
    }
    
    // 测试边界情况
    println!("\n测试边界情况:");
    match payment_context.execute_payment(0.0001) {
        Ok(result) => println!("结果: {}", result),
        Err(e) => println!("错误: {}", e),
    }
}

16.4 面向对象与Rust风格的权衡

Rust的哲学与面向对象编程

Rust的设计哲学与传统的面向对象语言有所不同,理解这些差异对于编写地道的Rust代码至关重要。

组合与继承的权衡
fn composition_vs_inheritance() {
    println!("=== 组合与继承的权衡 ===");
    
    // 传统OOP中的继承在Rust中通常用组合和trait实现
    
    // 示例:图形编辑器中的形状层次结构
    
    // 使用trait定义公共接口
    trait Shape {
        fn area(&self) -> f64;
        fn perimeter(&self) -> f64;
        fn draw(&self);
        fn description(&self) -> String {
            "一个形状".to_string()
        }
    }
    
    // 使用组合构建复杂形状
    struct Point {
        x: f64,
        y: f64,
    }
    
    impl Point {
        fn new(x: f64, y: f64) -> Self {
            Point { x, y }
        }
        
        fn distance_to(&self, other: &Point) -> f64 {
            ((self.x - other.x).powi(2) + (self.y - other.y).powi(2)).sqrt()
        }
    }
    
    // 简单的形状
    struct Circle {
        center: Point,  // 组合:Circle包含Point
        radius: f64,
    }
    
    impl Circle {
        fn new(center: Point, radius: f64) -> Self {
            Circle { center, radius }
        }
    }
    
    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 draw(&self) {
            println!("绘制圆形: 中心({}, {}), 半径{}", 
                     self.center.x, self.center.y, self.radius);
        }
        
        fn description(&self) -> String {
            format!("圆形 (半径: {})", self.radius)
        }
    }
    
    struct Rectangle {
        top_left: Point,    // 组合
        bottom_right: Point, // 组合
    }
    
    impl Rectangle {
        fn new(top_left: Point, bottom_right: Point) -> Self {
            Rectangle { top_left, bottom_right }
        }
        
        fn width(&self) -> f64 {
            (self.bottom_right.x - self.top_left.x).abs()
        }
        
        fn height(&self) -> f64 {
            (self.bottom_right.y - self.top_left.y).abs()
        }
    }
    
    impl Shape for Rectangle {
        fn area(&self) -> f64 {
            self.width() * self.height()
        }
        
        fn perimeter(&self) -> f64 {
            2.0 * (self.width() + self.height())
        }
        
        fn draw(&self) {
            println!("绘制矩形: 从({}, {})到({}, {})", 
                     self.top_left.x, self.top_left.y, 
                     self.bottom_right.x, self.bottom_right.y);
        }
        
        fn description(&self) -> String {
            format!("矩形 ({}x{})", self.width(), self.height())
        }
    }
    
    // 复杂形状:使用组合构建
    struct CompositeShape {
        shapes: Vec<Box<dyn Shape>>,
        name: String,
    }
    
    impl CompositeShape {
        fn new(name: &str) -> Self {
            CompositeShape {
                shapes: Vec::new(),
                name: name.to_string(),
            }
        }
        
        fn add_shape(&mut self, shape: Box<dyn Shape>) {
            self.shapes.push(shape);
        }
    }
    
    impl Shape for CompositeShape {
        fn area(&self) -> f64 {
            self.shapes.iter().map(|shape| shape.area()).sum()
        }
        
        fn perimeter(&self) -> f64 {
            // 对于复合形状,周长的概念可能没有明确定义
            // 这里简单返回所有形状周长之和
            self.shapes.iter().map(|shape| shape.perimeter()).sum()
        }
        
        fn draw(&self) {
            println!("绘制复合形状: {}", self.name);
            for shape in &self.shapes {
                shape.draw();
            }
        }
        
        fn description(&self) -> String {
            format!("复合形状: {} (包含{}个形状)", self.name, self.shapes.len())
        }
    }
    
    // 使用示例
    let circle = Circle::new(Point::new(0.0, 0.0), 5.0);
    let rectangle = Rectangle::new(Point::new(1.0, 1.0), Point::new(4.0, 3.0));
    
    let mut composite = CompositeShape::new("我的设计");
    composite.add_shape(Box::new(circle));
    composite.add_shape(Box::new(rectangle));
    
    let shapes: Vec<&dyn Shape> = vec![
        &composite,
    ];
    
    for shape in shapes {
        println!("{}", shape.description());
        println!("面积: {:.2}", shape.area());
        println!("周长: {:.2}", shape.perimeter());
        shape.draw();
        println!("---");
    }
}

数据导向设计与面向对象设计

Rust鼓励数据导向设计,这与传统的面向对象设计有所不同。

fn data_oriented_design() {
    println!("=== 数据导向设计与面向对象设计 ===");
    
    // 面向对象方式:将数据和行为封装在对象中
    struct OOPCharacter {
        name: String,
        health: u32,
        position: (f64, f64),
        velocity: (f64, f64),
    }
    
    impl OOPCharacter {
        fn new(name: &str, health: u32, position: (f64, f64)) -> Self {
            OOPCharacter {
                name: name.to_string(),
                health,
                position,
                velocity: (0.0, 0.0),
            }
        }
        
        fn update(&mut self, delta_time: f64) {
            self.position.0 += self.velocity.0 * delta_time;
            self.position.1 += self.velocity.1 * delta_time;
        }
        
        fn take_damage(&mut self, damage: u32) {
            self.health = self.health.saturating_sub(damage);
        }
        
        fn set_velocity(&mut self, velocity: (f64, f64)) {
            self.velocity = velocity;
        }
    }
    
    // 数据导向方式:将数据和行为分离
    struct DODCharacterData {
        name: String,
        health: u32,
    }
    
    struct PhysicsData {
        position: (f64, f64),
        velocity: (f64, f64),
    }
    
    struct DODWorld {
        character_data: Vec<DODCharacterData>,
        physics_data: Vec<PhysicsData>,
    }
    
    impl DODWorld {
        fn new() -> Self {
            DODWorld {
                character_data: Vec::new(),
                physics_data: Vec::new(),
            }
        }
        
        fn add_character(&mut self, name: &str, health: u32, position: (f64, f64)) {
            self.character_data.push(DODCharacterData {
                name: name.to_string(),
                health,
            });
            self.physics_data.push(PhysicsData {
                position,
                velocity: (0.0, 0.0),
            });
        }
        
        // 批量更新物理系统
        fn update_physics(&mut self, delta_time: f64) {
            for physics in &mut self.physics_data {
                physics.position.0 += physics.velocity.0 * delta_time;
                physics.position.1 += physics.velocity.1 * delta_time;
            }
        }
        
        // 批量处理伤害
        fn apply_damage_to_all(&mut self, damage: u32) {
            for character in &mut self.character_data {
                character.health = character.health.saturating_sub(damage);
            }
        }
        
        // 查找特定角色
        fn find_character_index(&self, name: &str) -> Option<usize> {
            self.character_data.iter().position(|c| c.name == name)
        }
        
        fn set_character_velocity(&mut self, index: usize, velocity: (f64, f64)) {
            if let Some(physics) = self.physics_data.get_mut(index) {
                physics.velocity = velocity;
            }
        }
    }
    
    println!("面向对象方式:");
    let mut oop_characters = vec![
        OOPCharacter::new("英雄", 100, (0.0, 0.0)),
        OOPCharacter::new("敌人", 50, (10.0, 5.0)),
    ];
    
    for character in &mut oop_characters {
        character.set_velocity((1.0, 0.5));
        character.update(1.0);
        character.take_damage(10);
    }
    
    println!("数据导向方式:");
    let mut dod_world = DODWorld::new();
    dod_world.add_character("英雄", 100, (0.0, 0.0));
    dod_world.add_character("敌人", 50, (10.0, 5.0));
    
    // 批量操作
    dod_world.set_character_velocity(0, (1.0, 0.5));
    dod_world.set_character_velocity(1, (0.5, 1.0));
    dod_world.update_physics(1.0);
    dod_world.apply_damage_to_all(10);
    
    println!("两种方式各有优劣:");
    println!("- 面向对象: 封装性好,易于理解单个对象的行为");
    println!("- 数据导向: 缓存友好,适合批量处理,性能通常更好");
}

性能考虑与设计选择

在Rust中选择面向对象模式时需要考虑性能影响。

fn performance_considerations() {
    println!("=== 性能考虑与设计选择 ===");
    
    use std::time::Instant;
    
    // 测试动态分发(trait对象)与静态分发(泛型)的性能差异
    
    trait Calculator {
        fn compute(&self, x: f64) -> f64;
    }
    
    struct SimpleCalculator;
    impl Calculator for SimpleCalculator {
        fn compute(&self, x: f64) -> f64 {
            x * x + 2.0 * x + 1.0
        }
    }
    
    struct ComplexCalculator;
    impl Calculator for ComplexCalculator {
        fn compute(&self, x: f64) -> f64 {
            x.sin() * x.cos().exp()
        }
    }
    
    // 使用trait对象(动态分发)
    fn process_dynamic(calculators: &[Box<dyn Calculator>], data: &[f64]) -> Vec<f64> {
        let mut results = Vec::with_capacity(data.len() * calculators.len());
        
        for calc in calculators {
            for &value in data {
                results.push(calc.compute(value));
            }
        }
        
        results
    }
    
    // 使用泛型(静态分发)
    fn process_static<C: Calculator>(calculators: &[C], data: &[f64]) -> Vec<f64> {
        let mut results = Vec::with_capacity(data.len() * calculators.len());
        
        for calc in calculators {
            for &value in data {
                results.push(calc.compute(value));
            }
        }
        
        results
    }
    
    // 性能测试
    let data: Vec<f64> = (0..1000).map(|i| i as f64 * 0.01).collect();
    let dynamic_calcs: Vec<Box<dyn Calculator>> = vec![
        Box::new(SimpleCalculator),
        Box::new(ComplexCalculator),
    ];
    
    let static_calcs = [SimpleCalculator, ComplexCalculator];
    
    // 测试动态分发
    let start = Instant::now();
    for _ in 0..1000 {
        let _ = process_dynamic(&dynamic_calcs, &data);
    }
    let dynamic_duration = start.elapsed();
    
    // 测试静态分发
    let start = Instant::now();
    for _ in 0..1000 {
        let _ = process_static(&static_calcs, &data);
    }
    let static_duration = start.elapsed();
    
    println!("动态分发耗时: {:?}", dynamic_duration);
    println!("静态分发耗时: {:?}", static_duration);
    println!("性能差异: {:.2}%", 
             (dynamic_duration.as_nanos() as f64 / static_duration.as_nanos() as f64 - 1.0) * 100.0);
    
    println!("\n设计建议:");
    println!("1. 在性能关键路径上优先使用静态分发(泛型)");
    println!("2. 需要运行时多态时使用动态分发(trait对象)");
    println!("3. 考虑使用枚举代替trait对象,如果类型集合是封闭的");
    println!("4. 对于热点代码,避免不必要的堆分配和动态分发");
}

实战:混合风格的系统设计

让我们设计一个实际的系统,展示如何在Rust中结合面向对象和其他范式。

fn hybrid_system_design() {
    println!("=== 混合风格的系统设计 ===");
    
    // 设计一个简单的游戏实体系统,结合面向对象和数据导向元素
    
    // 组件定义(数据导向)
    #[derive(Debug, Clone)]
    struct Position {
        x: f64,
        y: f64,
    }
    
    #[derive(Debug, Clone)]
    struct Velocity {
        dx: f64,
        dy: f64,
    }
    
    #[derive(Debug, Clone)]
    struct Health {
        current: u32,
        maximum: u32,
    }
    
    #[derive(Debug, Clone)]
    struct Name {
        value: String,
    }
    
    // 实体(面向对象风格)
    struct Entity {
        id: u32,
        components: std::collections::HashMap<std::any::TypeId, Box<dyn std::any::Any>>,
    }
    
    impl Entity {
        fn new(id: u32) -> Self {
            Entity {
                id,
                components: std::collections::HashMap::new(),
            }
        }
        
        fn add_component<T: 'static>(&mut self, component: T) {
            self.components.insert(std::any::TypeId::of::<T>(), Box::new(component));
        }
        
        fn get_component<T: 'static>(&self) -> Option<&T> {
            self.components
                .get(&std::any::TypeId::of::<T>())
                .and_then(|boxed| boxed.downcast_ref::<T>())
        }
        
        fn get_component_mut<T: 'static>(&mut self) -> Option<&mut T> {
            self.components
                .get_mut(&std::any::TypeId::of::<T>())
                .and_then(|boxed| boxed.downcast_mut::<T>())
        }
        
        fn has_component<T: 'static>(&self) -> bool {
            self.components.contains_key(&std::any::TypeId::of::<T>())
        }
    }
    
    // 系统(数据导向风格)
    struct PhysicsSystem;
    
    impl PhysicsSystem {
        fn update(&self, entities: &mut [Entity], delta_time: f64) {
            for entity in entities {
                if let (Some(position), Some(velocity)) = (
                    entity.get_component_mut::<Position>(),
                    entity.get_component::<Velocity>(),
                ) {
                    position.x += velocity.dx * delta_time;
                    position.y += velocity.dy * delta_time;
                }
            }
        }
    }
    
    struct RenderSystem;
    
    impl RenderSystem {
        fn render(&self, entities: &[Entity]) {
            for entity in entities {
                if let (Some(position), Some(name)) = (
                    entity.get_component::<Position>(),
                    entity.get_component::<Name>(),
                ) {
                    println!("渲染 {} 在位置 ({}, {})", name.value, position.x, position.y);
                }
            }
        }
    }
    
    // 使用示例
    let mut entities = vec![
        {
            let mut entity = Entity::new(1);
            entity.add_component(Name { value: "玩家".to_string() });
            entity.add_component(Position { x: 0.0, y: 0.0 });
            entity.add_component(Velocity { dx: 1.0, dy: 0.5 });
            entity.add_component(Health { current: 100, maximum: 100 });
            entity
        },
        {
            let mut entity = Entity::new(2);
            entity.add_component(Name { value: "敌人".to_string() });
            entity.add_component(Position { x: 5.0, y: 3.0 });
            entity.add_component(Velocity { dx: -0.5, dy: 0.2 });
            entity.add_component(Health { current: 50, maximum: 50 });
            entity
        },
    ];
    
    let physics_system = PhysicsSystem;
    let render_system = RenderSystem;
    
    println!("初始状态:");
    render_system.render(&entities);
    
    println!("\n更新物理:");
    physics_system.update(&mut entities, 1.0);
    render_system.render(&entities);
    
    println!("\n再次更新物理:");
    physics_system.update(&mut entities, 1.0);
    render_system.render(&entities);
    
    // 检查特定组件
    println!("\n组件检查:");
    for entity in &entities {
        if let Some(health) = entity.get_component::<Health>() {
            println!("实体 {} 生命值: {}/{}", 
                     entity.id, health.current, health.maximum);
        }
    }
}

fn main() {
    encapsulation_demo();
    composition_demo();
    method_syntax_demo();
    
    trait_objects_basics();
    advanced_trait_objects_demo();
    trait_object_limitations();
    
    factory_pattern_demo();
    observer_pattern_demo();
    strategy_pattern_demo();
    
    composition_vs_inheritance();
    data_oriented_design();
    performance_considerations();
    hybrid_system_design();
}

总结

Rust以独特的方式支持面向对象编程范式,通过结构体、枚举、trait和模式匹配等特性实现了封装、多态和代码复用。本章深入探讨了:

  1. 面向对象语言特性:封装、组合、方法语法等基本概念
  2. Trait对象:动态多态的实现方式和应用场景
  3. 设计模式:工厂模式、观察者模式、策略模式等在Rust中的实现
  4. 风格权衡:Rust哲学与面向对象编程的融合,性能考虑和设计选择

Rust不强制使用特定的编程范式,而是提供了灵活的工具集,让开发者能够根据具体需求选择最合适的模式。理解如何在Rust中有效地使用面向对象概念,同时充分利用Rust的强类型系统、所有权模型和零成本抽象,是编写高质量Rust代码的关键。

在下一章中,我们将探讨Rust中的模式和匹配,学习如何利用Rust强大的模式匹配功能来编写更简洁、更安全的代码。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐