如何在循环中正确使用期望method chaining的构建器模式?使用log4rs中的示例。请注意self
不是appender
中的引用。
//builder pattern from log4rs
pub struct ConfigBuilder {
appenders: Vec<Appender>,
loggers: Vec<Logger>,
}
impl ConfigBuilder {
pub fn appender(mut self, appender: Appender) -> ConfigBuilder {
self.appenders.push(appender);
self
}
}
执行此操作会导致错误,因为(我认为)cb
正在移动到.appender()
返回的内存中。
let cb = ConfigBuilder::new();
for x in ys {
cb.appender(x);
}
以下内容似乎有效。这是唯一的方法吗?
let mut cb = ConfigBuilder::new();
for x in ys {
cb = cb.appender(x);
}
答案 0 :(得分:4)
这是唯一的方法吗?
语义上它是关键的方式,虽然还有其他方法来编写它。 appender
函数需要mut self
,因此它将获取cb
变量值的所有权,并使该变量在该点之后无法使用。它可以设计为借用参考,但链接很好。由于您处于循环中,因此构建器需要在下一次迭代时可用,因此您需要将值分配给新的。这意味着
let mut cb = ConfigBuilder::new();
for x in ys {
cb = cb.appender(x);
}
确实是一种方法。另一种方法是使用Iterator
's .fold
来执行
let cb = ys.into_iter()
.fold(ConfigBuilder::new(), |cb, x| cb.appender(x));
将所有内容保留在一个作业中,但在其他方面几乎完全相同。