你是正确的,这两种类型确实不同。你可能会遇到生命周期问题。我猜你已经尝试过这个了:
let mut counter = Counter::new().incr().incr();
那样是失败的。然而,将它们分开:
let mut counter = Counter::new();
counter.incr().incr();
这很好用。编译器实际上会给你一个不错的提示:
help: consider using a `let` binding to increase its lifetime
就像我在评论中说的那样,为了“解决”在对象实例化过程中的流畅API设计问题,人们通常会创建一个Builder
类型(即“建造者模式”)。例如,您的建造者可能看起来像这样:
#[derive(Debug)]
struct Counter { count: u32 }
struct CounterBuilder { count: u32 }
impl CounterBuilder {
fn new() -> CounterBuilder {
CounterBuilder {
count: 0
}
}
fn incr(&mut self) -> &mut CounterBuilder {
self.count = self.count + 1;
self
}
fn build(&self) -> Counter {
Counter {
count: self.count
}
}
}
fn main() {
let counter = CounterBuilder::new()
.incr()
.incr()
.build();
println!("Counter value is: {}", counter.count);
assert_eq!(2, counter.count);
}
本质上,这个方法通过在build
调用后丢弃借用来解决生命周期问题(这表明您已经完成了CounterBuilder
实例)...此时,您将获得一个新的具体Counter
对象并准备就绪。
一旦您实例化了Counter
...您可以通过其自己的流畅API进行修改,例如:
let mut counter = CounterBuilder::new()
.incr()
.incr()
.build();
counter.local_increment().local_increment(); // For example, if you were to add a "local_increment" fluent method to Counter