Rust实现构建器模式和使用Bon库中的构建器

实现构建器模式的一种方式

这里参考资料2的文章,修改部分代码后如下。这段代码的目的是使用构建器模式创建和初始化Person对象。以下是各部分的解释:

  • 结构体定义

    • Person: 定义了一个结构体,包含name、age、address和sex四个字段。address和sex是可选的
    • PersonBuilder: 用于逐步构建Person对象的构建器结构体
  • 构建器实现

    • new: 创建一个新的PersonBuilder实例,初始化name和age,其他字段为None
    • with_address: 设置address字段,返回修改后的构建器
    • with_sex: 设置sex字段,返回修改后的构建器
    • build: 生成最终的Person对象
  • 主函数

    • 使用PersonBuilder构建一个Person对象,设置name、age、address和sex
    • 打印Person对象及其各个字段的值
  • 目的

    • 封装对象创建过程: 使用构建器模式来管理对象初始化的复杂性
    • 可选字段设置: 允许灵活地设置可选字段,而不必在创建对象时提供所有信息
    • 链式调用: 提供链式调用的接口,使代码更简洁易读
rust 复制代码
#[derive(Debug)]
struct Person {
    name: String,
    age: u32,
    address: Option<String>,
    sex: Option<String>,
}

struct PersonBuilder {
    name: String,
    age: u32,
    address: Option<String>,
    sex: Option<String>,
}

impl PersonBuilder {
    fn new(name: String, age: u32) -> Self {
        Self {
            name,
            age,
            address: None,
            sex: None,
        }
    }

    fn with_address(mut self, address: String) -> Self {
        self.address = Some(address);
        self
    }

    fn with_sex(mut self, sex: String) -> Self {
        self.sex = Some(sex);
        self
    }

    fn build(self) -> Person {
        Person {
            name: self.name,
            age: self.age,
            address: self.address,
            sex: self.sex,
        }
    }
}

fn main() {
    let person = PersonBuilder::new("Alice".to_string(), 30)
        .with_address("Wonderland".to_string())
        .with_sex("Female".to_string())
        .build();

    println!("{:?}", person);

    // Access the fields to demonstrate usage
    println!("Name: {}", person.name);
    println!("Age: {}", person.age);
    if let Some(address) = &person.address {
        println!("Address: {}", address);
    } else {
        println!("Address: None");
    }
    if let Some(sex) = &person.sex {
        println!("Sex: {}", sex);
    } else {
        println!("Sex: None");
    }
}
plaintext 复制代码
Person { name: "Alice", age: 30, address: Some("Wonderland"), sex: Some("Female") }
Name: Alice
Age: 30
Address: Wonderland
Sex: Female

使用Bon构建器

了解完Rust如何实现构建器模式后,如果我们想要在实际项目中使用构建器,当然可以不用自己手动实现,可以使用第三方库Bon,引入方式如下

Cargo.toml

toml 复制代码
[dependencies]
bon = "1.1.0"
rust 复制代码
use bon::bon;

#[derive(Debug)]
struct Person {
    name: String,
    age: u32,
    address: Option<String>,
    sex: Option<String>,
}

#[bon] // 使用 Bon 库的宏
impl Person {
    #[builder]
    fn new(name: String, age: u32) -> Self {
        Self {
            name,
            age,
            address: None,
            sex: None,
        }
    }

    #[builder]
    fn with_address(&mut self, address: String) {
        self.address = Some(address);    
    }

    #[builder]
    fn with_sex(&mut self, sex: String) {
        self.sex = Some(sex);
    }
}

fn main() {
    let mut person = Person::builder()
        .name("Alice".to_string())
        .age(30)    
        .build();
  
    person.with_address().address("Wonderland").call();
    person.with_sex().sex("Female").call();

    println!("{:?}", person);

    println!("Name: {}", person.name);
    println!("Age: {}", person.age);
    if let Some(address) = &person.address {
        println!("Address: {}", address);
    } else {
        println!("Address: None");
    }
    if let Some(sex) = &person.sex {
        println!("Sex: {}", sex);
    } else {
        println!("Sex: None");
    }
}
plaintext 复制代码
Person { name: "Alice", age: 30, address: Some("Wonderland"), sex: Some("Female") }
Name: Alice
Age: 30
Address: Wonderland
Sex: Female

运行结果和手动实现方式一致。当然这种方式更为简洁,可以省略很多代码实现,容易维护和阅读,更推荐使用

参考资料3,Bon除了结构体的构建器和关联方法的构建器,还有函数的构建器

rust 复制代码
fn main() {
    #[bon::builder] 
    fn greet(name: &str, age: u32) -> String {
        format!("Hello {name} with age {age}!")
    }

    let greeting = greet()
        .name("Bon") 
        .age(24)   
        .call();

    if greeting == "Hello Bon with age 24!" {
        println!("Assertion passed: {}", greeting);
    } else {
        println!("Assertion failed");
    }
}
plaintext 复制代码
Assertion passed: Hello Bon with age 24!

参考

  1. How to do named function arguments in Rust
  2. Rust 中的建造者模式 (qq.com)
  3. Overview | Bon (elastio.github.io)
相关推荐
假装我不帅44 分钟前
asp.net framework从webform开始创建mvc项目
后端·asp.net·mvc
神仙别闹1 小时前
基于ASP.NET+SQL Server实现简单小说网站(包括PC版本和移动版本)
后端·asp.net
计算机-秋大田1 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue
货拉拉技术2 小时前
货拉拉-实时对账系统(算盘平台)
后端
掘金酱2 小时前
✍【瓜分额外奖金】11月金石计划附加挑战赛-活动命题发布
人工智能·后端
代码之光_19802 小时前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
ajsbxi2 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
颜淡慕潇3 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
尘浮生4 小时前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea
尚学教辅学习资料4 小时前
基于SpringBoot的医药管理系统+LW示例参考
java·spring boot·后端·java毕业设计·医药管理