Rust设计模式与代码示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Rust中的设计模式:带示例的实践指南



设计模式是经过验证的典型开发问题解决方案。在Rust中,由于其独特的所有权系统和内存模型,经典模式的实现通常与带有垃圾收集的语言不同。在本文中,我们将分析三个关键模式:Singleton、Builder和Strategy,并根据Rust的特性进行调整。



1. Rust中的Singleton模式:无需unsafe的全局状态



Singleton确保一个类只有一个实例,并提供全局访问点。在Rust中,once_cell crate或稳定的std::sync::OnceLock(自Rust 1.70起)非常适合此目的。



使用OnceLock的实现

use std::sync::OnceLock;

pub struct Logger { level: String,}

impl Logger { pub fn global() -> &'static Logger { static INSTANCE: OnceLock<Logger> = OnceLock::new(); INSTANCE.get_or_init(|| Logger { level: "info".to_string(), }) }

pub fn log(&self, msg: &str) { println!("[{}] {}", self.level, msg); }}

fn main() { let logger = Logger::global(); logger.log("你好,Rust!"); // Logger::global() 将返回同一个实例}


优点:安全性(无unsafe)、惰性初始化、线程安全。缺点——全局状态使测试复杂化。



2. Builder模式:构建复杂对象



Builder将复杂对象的构建与其表示分离。在Rust中,它对于具有多个可选字段的结构特别有用。



示例:HTTP客户端配置

pub struct HttpClient {    url: String,    timeout: u64,    headers: Vec<(String, String)>,}

pub struct HttpClientBuilder { url: String, timeout: Option<u64>, headers: Vec<(String, String)>,}

impl HttpClientBuilder { pub fn new(url: &str) -> Self { HttpClientBuilder { url: url.to_string(), timeout: None, headers: vec![], } }

pub fn timeout(mut self, secs: u64) -> Self { self.timeout = Some(secs); self }

pub fn header(mut self, key: &str, value: &str) -> Self { self.headers.push((key.to_string(), value.to_string())); self }

pub fn build(self) -> HttpClient { HttpClient { url: self.url, timeout: self.timeout.unwrap_or(30), headers: self.headers, } }}

fn main() { let client = HttpClientBuilder::new("https://api.example.com") .timeout(10) .header("Authorization", "Bearer token123") .build(); println!("客户端URL: {}", client.url);}


重要:在builder的方法中使用self(而不是&self)可以避免克隆并使API更符合人体工程学。



3. Strategy模式:作为可互换策略的算法



Strategy定义了一系列算法,封装每个算法并使它们可以互换。在Rust中,这是通过traits和动态分发(Box<dyn Trait>)实现的。



示例:排序系统

trait SortStrategy {    fn sort(&self, data: &mut [i32]);}

struct BubbleSort;impl SortStrategy for BubbleSort { fn sort(&self, data: &mut [i32]) { let n = data.len(); for i in 0..n { for j in 0..n - i - 1 { if data[j] > data[j + 1] { data.swap(j, j + 1); } } } }}

struct QuickSort;impl SortStrategy for QuickSort { fn sort(&self, da

博客

书籍推荐