使用 to_owned() 是更新结构的惯用方法吗?
Is using to_owned() the idiomatic way to update a struct in place?
我正在尝试使用链式方法就地更新 Rust 结构。我找到了一种方法来做到这一点,但我不确定我下面的代码是惯用的 Rust 还是只是一种变通方法。
特别是,我在链接方法的末尾使用 .to_owned()
到 return 借用的结构。代码编译并工作得很好。这是最小的例子。
//struct.rs
#[derive(Debug, Default, Clone, PartialEq)]
pub struct ModelDataCapture {
run: i32,
year: i32,
}
impl ModelDataCapture {
pub fn new() -> Self {
ModelDataCapture::default()
}
pub fn set_run(&mut self, run: i32) -> &mut ModelDataCapture {
self.run = run;
self
}
pub fn set_year(&mut self, year: i32) -> &mut ModelDataCapture {
self.year = year;
self
}
}
//main.rs
let data_capture = ModelDataCapture::new()
.set_run(0)
.set_year(1)
.to_owned(); // <<< QUESTION
println!("here is the data capture {:?}", data_capture);
这是编写结构就地修改的正确方法吗?如果我不在链的末尾包含 .to_owned()
方法,编译将失败并显示一条消息,指出临时变量的寿命不够长。
你的代码 "works" 但对我来说没有意义。它:
- 创造价值
- 改变值
- 克隆值
- 丢弃原始值
看到效率低下了吗?另外,所有的"in-place mutation"都被完全丢弃了,所以对它没有任何好处。
我通常会引入一个绑定到 mutate:
let mut data_capture = ModelDataCapture::new();
data_capture.set_run(0).set_year(1);
或者一路走下去,创建一个具有 finish
或 build
等价物的构建器
#[derive(Debug)]
struct ModelDataCapture {
run: i32,
year: i32,
}
#[derive(Debug, Default)]
struct ModelDataCaptureBuilder {
run: i32,
year: i32,
}
impl ModelDataCaptureBuilder {
fn set_run(self, run: i32) -> Self {
ModelDataCaptureBuilder { run, ..self }
}
fn set_year(self, year: i32) -> Self {
ModelDataCaptureBuilder { year, ..self }
}
fn build(self) -> ModelDataCapture {
let ModelDataCaptureBuilder { run, year } = self;
ModelDataCapture { run, year }
}
}
fn main() {
let data_capture = ModelDataCaptureBuilder::default().set_run(0).set_year(1).build();
println!("here is the data capture {:?}", data_capture);
}
有关反映构建项目的构建器的更多示例,请参阅 。
您可以在第一个示例中按值获取 self
,但在大多数情况下这很烦人,因为您始终必须记住绑定结果。
您可以更改函数以获取自我和 return 自我的所有权。
因为每个“setter”方法 return 都是 self 的所有权,所以这段代码应该运行良好。
欲了解更多信息,请查看 rust book
//struct.rs
#[derive(Debug, Default, Clone, PartialEq)]
pub struct ModelDataCapture {
run: i32,
year: i32,
}
impl ModelDataCapture {
pub fn new() -> Self {
ModelDataCapture::default()
}
pub fn set_run(mut self, run: i32) -> ModelDataCapture {
self.run = run;
self
}
pub fn set_year(mut self, year: i32) -> ModelDataCapture {
self.year = year;
self
}
}
fn main() {
//main.rs
let data_capture = ModelDataCapture::new().set_run(0).set_year(1);
println!("here is the data capture {:?}", data_capture);
}
我正在尝试使用链式方法就地更新 Rust 结构。我找到了一种方法来做到这一点,但我不确定我下面的代码是惯用的 Rust 还是只是一种变通方法。
特别是,我在链接方法的末尾使用 .to_owned()
到 return 借用的结构。代码编译并工作得很好。这是最小的例子。
//struct.rs
#[derive(Debug, Default, Clone, PartialEq)]
pub struct ModelDataCapture {
run: i32,
year: i32,
}
impl ModelDataCapture {
pub fn new() -> Self {
ModelDataCapture::default()
}
pub fn set_run(&mut self, run: i32) -> &mut ModelDataCapture {
self.run = run;
self
}
pub fn set_year(&mut self, year: i32) -> &mut ModelDataCapture {
self.year = year;
self
}
}
//main.rs
let data_capture = ModelDataCapture::new()
.set_run(0)
.set_year(1)
.to_owned(); // <<< QUESTION
println!("here is the data capture {:?}", data_capture);
这是编写结构就地修改的正确方法吗?如果我不在链的末尾包含 .to_owned()
方法,编译将失败并显示一条消息,指出临时变量的寿命不够长。
你的代码 "works" 但对我来说没有意义。它:
- 创造价值
- 改变值
- 克隆值
- 丢弃原始值
看到效率低下了吗?另外,所有的"in-place mutation"都被完全丢弃了,所以对它没有任何好处。
我通常会引入一个绑定到 mutate:
let mut data_capture = ModelDataCapture::new();
data_capture.set_run(0).set_year(1);
或者一路走下去,创建一个具有 finish
或 build
#[derive(Debug)]
struct ModelDataCapture {
run: i32,
year: i32,
}
#[derive(Debug, Default)]
struct ModelDataCaptureBuilder {
run: i32,
year: i32,
}
impl ModelDataCaptureBuilder {
fn set_run(self, run: i32) -> Self {
ModelDataCaptureBuilder { run, ..self }
}
fn set_year(self, year: i32) -> Self {
ModelDataCaptureBuilder { year, ..self }
}
fn build(self) -> ModelDataCapture {
let ModelDataCaptureBuilder { run, year } = self;
ModelDataCapture { run, year }
}
}
fn main() {
let data_capture = ModelDataCaptureBuilder::default().set_run(0).set_year(1).build();
println!("here is the data capture {:?}", data_capture);
}
有关反映构建项目的构建器的更多示例,请参阅
您可以在第一个示例中按值获取 self
,但在大多数情况下这很烦人,因为您始终必须记住绑定结果。
您可以更改函数以获取自我和 return 自我的所有权。 因为每个“setter”方法 return 都是 self 的所有权,所以这段代码应该运行良好。 欲了解更多信息,请查看 rust book
//struct.rs
#[derive(Debug, Default, Clone, PartialEq)]
pub struct ModelDataCapture {
run: i32,
year: i32,
}
impl ModelDataCapture {
pub fn new() -> Self {
ModelDataCapture::default()
}
pub fn set_run(mut self, run: i32) -> ModelDataCapture {
self.run = run;
self
}
pub fn set_year(mut self, year: i32) -> ModelDataCapture {
self.year = year;
self
}
}
fn main() {
//main.rs
let data_capture = ModelDataCapture::new().set_run(0).set_year(1);
println!("here is the data capture {:?}", data_capture);
}