如何正确使用期望的构建器模式方法链接 https://en.wikipedia.org/wiki/Method_chaining在循环中?使用来自的示例log4rs https://crates.io/crates/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);
}
这是唯一的方法吗?
从语义上讲,它是关键方式,尽管还有其他方式来编写它。这appender
函数需要mut self
所以它将取得所有权cb
变量的值并使该变量在该点之后不可用。它本来可以被设计为借用参考,但链接很好。由于您处于循环中,因此构建器需要在下一次迭代中可用,因此您需要将值分配给新的内容。这意味着
let mut cb = ConfigBuilder::new();
for x in ys {
cb = cb.appender(x);
}
确实是一种方法。另一种方法是使用Iterator's .fold https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.fold to do
let cb = ys.into_iter()
.fold(ConfigBuilder::new(), |cb, x| cb.appender(x));
它将所有内容保留在一项作业中,但其他方面几乎相同。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)