Rust高级设计模式:代码示例

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

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

开始课程

Rust设计模式:高级示例与实战

\n\n

设计模式是经过验证的典型问题解决方案,有助于创建灵活、可维护且可扩展的架构。在Rust中,凭借其所有权、借用和特质系统,许多经典模式具有独特的实现方式。本文将深入剖析在Rust生态系统中特别高效的高级设计模式。

\n\n

1. 高级Builder(建造者)模式

\n\n

经典的Builder模式在Rust中通常通过返回&mut Self的方法链来实现。然而,在高级层面,我们使用带状态类型的类型化Builder,以确保在编译阶段的正确性。

\n\n

问题:必填字段的控制

\n

普通的Builder无法保证用户填写了所有必填字段。我们可能会忘记调用.build()或未设置关键参数。

\n\n

解决方案:带幽灵类型的Builder

\n
use std::marker::PhantomData;\n\n// 字段的状态类型\nstruct UsernameNotSet;\nstruct UsernameSet;\nstruct PasswordNotSet;\nstruct PasswordSet;\n\nstruct UserBuilder<U, P> {\n    username: Option<String>,\n    password: Option<String>,\n    _username: PhantomData<U>,\n    _password: PhantomData<P>,\n}\n\nimpl UserBuilder<UsernameNotSet, PasswordNotSet> {\n    pub fn new() -> Self {\n        Self {\n            username: None,\n            password: None,\n            _username: PhantomData,\n            _password: PhantomData,\n        }\n    }\n}\n\nimpl<P> UserBuilder<UsernameNotSet, P> {\n    pub fn username(mut self, name: &str) -> UserBuilder<UsernameSet, P> {\n        self.username = Some(name.to_string());\n        UserBuilder {\n            username: self.username,\n            password: self.password,\n            _username: PhantomData,\n            _password: PhantomData,\n        }\n    }\n}\n\nimpl<U> UserBuilder<U, PasswordNotSet> {\n    pub fn password(mut self, pwd: &str) -> UserBuilder<U, PasswordSet> {\n        self.password = Some(pwd.to_string());\n        UserBuilder {\n            username: self.username,\n            password: self.password,\n            _username: PhantomData,\n            _password: PhantomData,\n        }\n    }\n}\n\nimpl UserBuilder<UsernameSet, PasswordSet> {\n    pub fn build(self) -> User {\n        User {\n            username: self.username.expect("Username must be set"),\n            password: self.password.expect("Password must be set"),\n        }\n    }\n}\n\npub struct User {\n    pub username: String,\n    pub password: String,\n}\n\nfn main() {\n    // 现在编译器不允许在未设置两个字段的情况下调用build()\n    let user = UserBuilder::new()\n        .username("alice")\n        .password("secret123")\n        .build();\n    println!("User: {}", user.username);\n}
\n\n

优势:"忘记字段"的错误在编译阶段被检测到,而非运行时。

\n\n

2. 通过特质实现的State(状态)模式

\n\n

State模式允许对象在内部状态改变时改变其行为。在Rust中,这可以通过枚举(enum)和特质优雅地实现。

\n\n

使用枚举的实现

\n
enum ConnectionState {\n    Disconnected,\n    Connecting,\n    Connected,\n}\n\nstruct Connection {\n    state: ConnectionState,\n}\n\nimpl Connection {\n    pub fn new() -> Self {\n        Self { state: ConnectionState::Disconnected }\n    }\n\n    pub fn connect(&mut self) {\n        match self.state {\n            ConnectionState::Disconnected => {\n                println!("开始连接...");\n                self.state = ConnectionState::Connecting;\n            }\n            ConnectionState::Connecting => {\n                printl                

博客

书籍推荐