有时候你会遇到这样的事情:
let mut something = Something::new();
something.set_property_a("foo");
something.set_property_b("bar");
let result = something.result();
您所需要的只是结果,但现在作用域被某些东西
污染了。
在 Kotlin 中,您可以这样做(在其他版本中,但为了清楚起见使用冗长的版本):
val result = Something().let { x ->
x.propertyA = "foo"
x.propertyB = "bar"
x.result()
}
T.let(closure)
只是运行闭包,将调用它的对象(Something
的实例)作为参数并返回闭包返回的任何内容。极其轻巧和简单的概念,但非常有帮助。
在 Rust 中可以做类似的事情吗?我想出的最接近的是:
let result = {
let mut x = Something::new();
x.set_property_a("foo");
x.set_property_b("boo");
x.result()
};
最佳答案
您可以使用 builder pattern .这是 Rust 中实现你想要的东西的惯用方式:
#[derive(Debug)]
struct Something {
property_a: String,
property_b: String,
}
#[derive(Debug, Default)]
struct SomethingBuilder {
property_a: Option<String>,
property_b: String,
}
#[derive(Debug)]
enum BuildError {
ANotSet,
}
impl SomethingBuilder {
fn new() -> Self {
Self::default()
}
fn with_a(mut self, a: String) -> Self {
self.property_a = Some(a);
self
}
fn with_b(mut self, b: String) -> Self {
self.property_b = b;
self
}
fn build(self) -> Result<Something, BuildError> {
Ok(Something {
property_a: self.property_a.ok_or(BuildError::ANotSet)?,
property_b: self.property_b,
})
}
}
fn main() {
let thing = SomethingBuilder::new()
.with_a("foo".into())
.with_b("bar".into())
.build() // returns BuildError if set_a is left out
.unwrap();
println!("{:?}", thing);
}
参见 this real world usage例如。
在构建器结构中,您可以在调用 build
方法时进行所有您想要的验证。如果一切正常,就可以返回新建的struct
。这种模式的优点是代码的可读性(无“污染”)和为用户保证构建的struct
是完全有效的。
关于rust - 在单个表达式中创建、初始化和运行的惯用方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47822002/