实现构建器模式的一种方式
这里参考资料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对象及其各个字段的值
目的
- 封装对象创建过程: 使用构建器模式来管理对象初始化的复杂性
- 可选字段设置: 允许灵活地设置可选字段,而不必在创建对象时提供所有信息
- 链式调用: 提供链式调用的接口,使代码更简洁易读
#[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");
}
}person { name: "alice", age: 30, address: some("wonderland"), sex: some("female") }
name: alice
age: 30
address: wonderland
sex: female使用bon构建器
了解完rust如何实现构建器模式后,如果我们想要在实际项目中使用构建器,当然可以不用自己手动实现,可以使用第三方库bon,引入方式如下
cargo.toml
[dependencies] bon = "1.1.0"
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");
}
}person { name: "alice", age: 30, address: some("wonderland"), sex: some("female") }
name: alice
age: 30
address: wonderland
sex: female运行结果和手动实现方式一致。当然这种方式更为简洁,可以省略很多代码实现,容易维护和阅读,更推荐使用
参考资料3,bon除了结构体的构建器和关联方法的构建器,还有函数的构建器
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");
}
}assertion passed: hello bon with age 24!
参考资料
how to do named function arguments in rust
overview | bon (elastio.github.io)
到此这篇关于rust实现构建器模式和使用bon库中的构建器的文章就介绍到这了,更多相关rust构建器模式内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论