【发布时间】:2018-05-15 06:04:28
【问题描述】:
我正在尝试使用 quick-xml 封装一个 XML 解析器,该解析器需要一些特定的 XML 条目。主要代码如下:
pub struct GPXParser<B: BufRead> {
reader: Reader<B>,
buff: Vec<u8>,
}
impl<B> GPXParser<B> {
pub fn read_next<a>(&mut self) -> Result<XMLCache, Error> {
match self.reader.read_event(&mut self.buff) {
Ok(XMLEvent::Start(ref e)) if e.name() == b"wpt" => {
self.read_next_wpt() // --> Multiple mutable borrows error
}
_ => Err(Error::NoCaches),
}
}
fn read_next_wpt(&mut self) -> Result<XMLCache, Error> {
match self.reader.read_event(&mut self.buff) {
_ => Err(Error::NoCaches),
}
}
}
然后我在 rust-lang.org 上阅读了这个 topic,提到:
惯用的 Rust 代码通常避免持有对可变对象内部的长期引用,并倾向于使用不可变引用或独立值的替代方法
我尝试使用中间 buff 元素来改变我的方法:
pub struct GPXParser<B: BufRead> {
reader: Reader<B>,
}
impl<B> GPXParser<B> {
pub fn read_next<a>(&mut self) -> Result<XMLCache, Error> {
let mut buff: Vec<u8> = Vec::new();
match self.reader.read_event(&mut buff) {
Ok(XMLEvent::Start(ref e)) if e.name() == b"wpt" => {
self.read_next_wpt(&mut buff) // --> Multiple mutable borrows error
}
_ => Err(Error::NoCaches),
}
}
fn read_next_wpt(&mut self, buff: &mut Vec<u8>) -> Result<XMLCache, Error> {
match self.reader.read_event(buff) {
_ => Err(Error::NoCaches),
}
}
}
我没有改变方法。
我试图将match 语句分成两行:
pub fn read_next<a>(&mut self) -> Result<XMLCache, Error> {
let result = self.reader.read_event(&mut self.buff);
match result {
Ok(XMLEvent::Start(ref e)) if e.name() == b"wpt" => self.read_next_wpt(),
_ => Err(Error::NoCaches),
}
}
但我得到了同样的错误:
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/gpx/mod.rs:34:17
|
31 | let result = self.reader.read_event(&mut self.buff);
| --------- first mutable borrow occurs here
...
34 | self.read_next_wpt()
| ^^^^ second mutable borrow occurs here
...
39 | }
| - first borrow ends here
有没有办法在不同的方法调用中使用相同的缓冲区?
应该在游戏中加入一些生命吗?
如果不是,解决这个问题的惯用 Rust 方法是什么?
【问题讨论】:
-
你为什么使用
XMLEvent::Start(ref e)?为什么不XMLEvent::Start(e) -
我只是看了一下存储库 github.com/tafia/quick-xml 上的自述文件。这有什么含义吗?两者有什么区别?
-
如果你删除
ref,它会编译吗?如果有,我会写一个答案 -
否 :( 我还有另一个错误
cannot bind by-move into a pattern guard,它指向e符号,其解释是`将值移动到模式保护中`
标签: rust borrow-checker