用一种expression方式创建,初始化和运行的习惯性方法

有时你有这样的事情:

let mut something = Something::new(); something.set_property_a("foo"); something.set_property_b("bar"); let result = something.result(); 

你所需要的只是结果,但现在范围被污染something

在Kotlin中,你可以像这样做(在其他版本中,但为了清晰起见,使用详细的):

 val result = Something().let { x -> x.propertyA = "foo" x.propertyB = "bar" x.result() } 

T.let(closure)只是运行闭T.let(closure)它的对象( Something的实例)作为参数,并返回闭包返回的任何东西。 非常轻量级和简单的概念,但非常有帮助。

在Rust里能做什么类似的事情吗? 我最近想出的是:

 let result = { let mut x = Something::new(); x.set_property_a("foo"); x.set_property_b("boo"); x.result() }; 

您可以使用生成器模式 。 这是鲁斯惯用的方式来实现你想要的东西:

 #[derive(Debug)] struct Something { property_a: String, property_b: String, } #[derive(Debug, Default)] struct SomethingBuilder { property_a: Option, 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 { 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); } 

例如,看看这个真实世界的用法 。

在构建器结构中,可以在调用build方法时执行所需的所有validation。 如果一切正常,您可以返回新建的struct 。 这种模式的优点是代码的可读性(无“污染”), 保证用户的构建完全有效。