在许多其他语言中,通常会有类似的API
obj.do_x()
.do_y()
Run Code Online (Sandbox Code Playgroud)
在Rust中我遇到了一个问题,if do_x,do_ytake &mut self,类型不匹配.有没有一种优雅的方法来解决这个问题?
例如:
#[derive(Debug)]
struct Counter { count: u32 }
impl Counter {
fn incr(&mut self) -> &mut Counter {
self.count = self.count + 1;
self
}
fn new() -> Counter {
Counter {
count: 0
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,new()返回a Counter,但是流畅的API需求mut Counter.
你为什么要使用参考?
#[derive(Debug)]
struct Counter { count: u32 }
impl Counter {
fn incr(mut self) -> Counter {
self.count = self.count + 1;
self
}
fn new() -> Counter {
Counter {
count: 0
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您使用原始版本,则不再存在借用问题:)
注意:虽然适用于构建器模式,但对于常规类型可能会很烦人.
你是对的,类型不同.你可能会遇到终身问题.我假设你试过这个:
let mut counter = Counter::new().incr().incr();
Run Code Online (Sandbox Code Playgroud)
那失败了.然而,拆分出来:
let mut counter = Counter::new();
counter.incr().incr();
Run Code Online (Sandbox Code Playgroud)
..工作良好.编译器实际上会给你一个体面的提示:
help: consider using a `let` binding to increase its lifetime
Run Code Online (Sandbox Code Playgroud)
正如我在评论中所说的那样,在对象实例化期间"解决"这种流畅的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); // Should print 2
assert_eq!(2, counter.count);
}
Run Code Online (Sandbox Code Playgroud)
从本质上讲,这可以通过在build调用之后放弃借用来解决生命周期问题(它注意到你已经完成了a的实例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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
377 次 |
| 最近记录: |