Rust设计模式详解:从入门到精通

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

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

开始课程

Rust设计模式:从理论到实践



设计模式是软件开发中经过验证的常见问题解决方案。在Rust中,由于其独特的所有权(ownership)系统以及缺乏经典的面向对象编程,许多经典模式呈现出新的面貌。本文将介绍四种关键模式:Singleton、Factory、Builder和Strategy,并针对惯用的Rust进行适配。



1. Rust中的Singleton(单例模式)



Rust没有传统意义上的全局静态变量。然而,可以通过lazy_static或OnceCell实现Singleton。下面是一个使用std::sync::OnceLock(自Rust 1.70起可用)的示例。



使用OnceLock实现



use std::sync::OnceLock;

static CONFIG: OnceLock<Config> = OnceLock::new();

#[derive(Debug)]struct Config { db_url: String, port: u16,}

fn get_config() -> &'static Config { CONFIG.get_or_init(|| { Config { db_url: String::from("postgres://localhost"), port: 5432, } })}

fn main() { let cfg = get_config(); println!("{:?}", cfg);}


关键点: OnceLock保证一次性初始化且线程安全。这是Rust中的惯用方式。



2. 通过trait实现Factory(工厂模式)



Rust中的Factory模式可以通过trait很好地实现。我们不需要抽象类——只需通过trait定义接口即可。



示例:创建交通工具



trait Transport {    fn deliver(&self);}

struct Truck;impl Transport for Truck { fn deliver(&self) { println!("陆路卡车运输"); }}

struct Ship;impl Transport for Ship { fn deliver(&self) { println!("海路轮船运输"); }}

struct LogisticsFactory;

impl LogisticsFactory { fn create_transport(route_type: &str) -> Box<dyn Transport> { match route_type { "land" => Box::new(Truck), "sea" => Box::new(Ship), _ => panic!("未知的路线类型"), } }}

fn main() { let transport = LogisticsFactory::create_transport("sea"); transport.deliver();}


优势: Rust不需要继承——多态通过trait和Box<dyn Trait>实现。



3. 带类型化链式调用的Builder(构建器模式)



Builder在Rust中被广泛使用,特别是对于具有多个可选参数的结构体。我们通过返回&mut Self的类型化方法链来实现它。



示例:创建HTTP请求



#[derive(Debug, Default)]struct HttpRequest {    url: String,    method: String,    headers: Vec<(String, String)>,    body: Option<String>,}

struct HttpRequestBuilder { request: HttpRequest,}

impl HttpRequestBuilder { fn new(url: &str) -> Self { HttpRequestBuilder { request: HttpRequest { url: url.to_string(), method: "GET".to_string(), ..Default::default() }, } }

fn method(&mut self, method: &str) -> &mut Self { self.request.method = method.to_string(); self }

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

fn body(&mut self, body: &str) -> &mut Self { self.request.body = Some(body.to_string()); self }

fn build(&self) -> HttpRequest { // 此处可添加验证逻辑 HttpRequest { ..self.request.clone() } }}

fn ma

博客

书籍推荐