请考虑以下代码(也可在playground上查看):
我感到惊讶的是,我并不清楚这里是如何两次借用
假设我是正确的,我通过使用一个
pub trait TextStream {
fn next_str(&mut self) -> Option<&str>;
}
pub struct FilterTextStream<T: TextStream> {
inner: T,
maxlen: usize,
}
impl<T: TextStream> TextStream for FilterTextStream<T> {
fn next_str(&mut self) -> Option<&str> {
match self.inner.next_str() {
None => None,
Some(txt) if txt.len() <= self.maxlen => {
Some(txt) // <-- this does not compile
//Some(unsafe {&*(txt as *const str)}) // <-- this fixes the problem
}
_ => self.next_str()
}
}
}
TextStream
特性类似于迭代器,但其产生的 &str
不具有重叠的生命周期。而 FilterTextStream
则类似于(专门化的)过滤器迭代器。然而,该代码无法编译,出现以下错误:
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/main.rs:18:18
|
11 | fn next_str(&mut self) -> Option<&str> {
| - let's call the lifetime of this reference `'1`
12 | match self.inner.next_str() {
| ---------- first mutable borrow occurs here
...
15 | Some(txt)
| --------- returning this value requires that `self.inner` is borrowed for `'1`
...
18 | _ => self.next_str()
| ^^^^ second mutable borrow occurs here
我感到惊讶的是,我并不清楚这里是如何两次借用
self
。我们要么在第15行返回,要么在第18行返回,只会发生其中之一。我的假设是,这不是一个真正的问题,而是一个借用检查器无法智能处理的情况。我有什么遗漏的吗?假设我是正确的,我通过使用一个
unsafe
块(请参见注释掉的第16行)来绕过这个错误,人为地 "破坏" 生命周期依赖关系。有没有更好的方法(即没有任何 unsafe
块)可以使这段代码编译?