Предположим, у меня есть несколько структур, как в следующем примере, и в методе next()
мне нужно извлечь следующее событие, используя предоставленный пользователем буфер, но если это событие является комментарием, а флаг игнорируемых комментариев установлен направда, мне нужно снова получить следующее событие:
struct Parser {
ignore_comments: bool,
}
enum XmlEvent<'buf> {
Comment(&'buf str),
Other(&'buf str),
}
impl Parser {
fn next<'buf>(&mut self, buffer: &'buf mut String) -> XmlEvent<'buf> {
let result = loop {
buffer.clear();
let temp_event = self.parse_outside_tag(buffer);
match temp_event {
XmlEvent::Comment(_) if self.ignore_comments => {}
_ => break temp_event,
}
};
result
}
fn parse_outside_tag<'buf>(&mut self, _buffer: &'buf mut String) -> XmlEvent<'buf> {
unimplemented!()
}
}
Этот код, однако, выдает двойную ошибку заимствования, даже когда у меня включено #![feature(nll)]
:
error[E0499]: cannot borrow `*buffer` as mutable more than once at a time
--> src/main.rs:14:13
|
14 | buffer.clear();
| ^^^^^^ second mutable borrow occurs here
15 |
16 | let temp_event = self.parse_outside_tag(buffer);
| ------ first mutable borrow occurs here
|
note: borrowed value must be valid for the lifetime 'buf as defined on the method body at 12:5...
--> src/main.rs:12:5
|
12 | fn next<'buf>(&mut self, buffer: &'buf mut String) -> XmlEvent<'buf> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0499]: cannot borrow `*buffer` as mutable more than once at a time
--> src/main.rs:16:53
|
16 | let temp_event = self.parse_outside_tag(buffer);
| ^^^^^^ mutable borrow starts here in previous iteration of loop
|
note: borrowed value must be valid for the lifetime 'buf as defined on the method body at 12:5...
--> src/main.rs:12:5
|
12 | fn next<'buf>(&mut self, buffer: &'buf mut String) -> XmlEvent<'buf> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
Iможет (хотя бы приблизительно) понять, почему здесь может происходить ошибка с отключенной функцией NLL, но я не понимаю, почему это происходит с NLL.
В любом случае, моя конечная цель - реализовать это без флагов,поэтому я также попытался сделать это (это рекурсивно, что очень печально, но все нерекурсивные версии, которые я придумал, не могли работать без NLL):
fn next<'buf>(&mut self, buffer: &'buf mut String) -> XmlEvent<'buf> {
buffer.clear();
{
let temp_event = self.parse_outside_tag(buffer);
match temp_event {
XmlEvent::Comment(_) if self.ignore_comments => {}
_ => return temp_event,
}
}
self.next(buffer)
}
Здесь я попытался ограничить заимствованиевнутри лексического блока, и ничего из этого блока не вытекает наружу.Тем не менее, я все еще получаю сообщение об ошибке:
error[E0499]: cannot borrow `*buffer` as mutable more than once at a time
--> src/main.rs:23:19
|
15 | let temp_event = self.parse_outside_tag(buffer);
| ------ first mutable borrow occurs here
...
23 | self.next(buffer)
| ^^^^^^ second mutable borrow occurs here
24 | }
| - first borrow ends here
error: aborting due to previous error
И снова, NLL не исправляет это.
Прошло много времени с тех пор, как я столкнулся с ошибкой проверки заимствования, которую я получаюЯ не понимаю, поэтому я надеюсь, что на самом деле это нечто простое, что я почему-то упускаю из виду :)
Я действительно подозреваю, что основная причина так или иначе связана с явным временем жизни 'buf
(в частности,ошибки, отмеченные флагом NLL, содержат эти примечания), но я не могу понять, что именно здесь не так.