我的实际问题可以通过变通解决,但我不知道为什么变通可以解决,而原始版本却不能.
我有这些类型:
struct Lexer<'source> { ... }
impl<'source> Iterator for Lexer<'source> {
type Item = Token<'source>;
...
}
struct Func<'source> { ... }
以下功能不起作用:
fn parse_tokens<'source>(lexer: &'source mut Lexer<'source>) -> Vec<Func> {
let mut funcs = Vec::new();
loop {
let Some(t) = lexer.next() else { break; }
funcs.push(parse_fn(lexer));
}
funcs
}
pub fn parse_fn<'source>(lexer: &'source mut Lexer<'source>) -> Func {
// Get the name of the function.
// TODO: replace all of these unwraps and panics with error handling.
let t = lexer.next().unwrap();
if t.kind != TokenKind::Identifier { panic!() }
let ident = t.value;
let mut body = Vec::new();
loop {
let Some(t) = lexer.next() else { break };
match t.kind {
TokenKind::Keyword(Keyword::End) => break,
TokenKind::Int(num) => body.push(Op::PushInt(num)),
kind => todo!("parsing of {kind:?}"),
}
}
Func {
ident,
body
}
}
编译失败,出现以下错误:
error[E0499]: cannot borrow `*lexer` as mutable more than once at a time
--> src/parse.rs:44:23
|
41 | pub fn parse_tokens<'source>(lexer: &'source mut Lexer<'source>) -> Vec<Func> {
| ------- lifetime `'source` defined here
...
44 | let Some(t) = lexer.next() else { break };
| ^^^^^^^^^^^^ second mutable borrow occurs here
45 | match t.kind {
46 | TokenKind::Keyword(Keyword::Fn) => funcs.push(parse_fn(lexer)),
| ---------------
| | |
| | first mutable borrow occurs here
| argument requires that `*lexer` is borrowed for `'source`
error[E0499]: cannot borrow `*lexer` as mutable more than once at a time
--> src/parse.rs:46:68
|
41 | pub fn parse_tokens<'source>(lexer: &'source mut Lexer<'source>) -> Vec<Func> {
| ------- lifetime `'source` defined here
...
46 | TokenKind::Keyword(Keyword::Fn) => funcs.push(parse_fn(lexer)),
| ---------^^^^^-
| | |
| | `*lexer` was mutably borrowed here in the previous iteration of the loop
| argument requires that `*lexer` is borrowed for `'source`
然而--这是我感到奇怪的部分--如果我不使用可变的borrow ,而是来回传递所有权,代码就会按预期进行编译和工作.
特别是,通过如下方式更新函数及其签名:
pub fn parse_tokens<'source>(mut lexer: Lexer<'source>) -> Vec<Func> {
...
TokenKind::Keyword(Keyword::Fn) => {
let func;
(lexer, func) = parse_fn(lexer);
funcs.push(func);
}
...
}
pub fn parse_fn<'source>(mut lexer: Lexer<'source>) -> (Lexer<'source>, Func) {
...
(lexer, Func {
ident,
body
})
}
我的印象是,第一个示例不起作用,因为borrow 判断器认为funcs
将包含lexer
指向的数据,而funcs
比可变borrow 更持久.但考虑到编译后的版本,情况不可能是这样.
任何有助于理解这一点的帮助/解释都将不胜感激.
如果需要进一步的信息或完整的工作实例,我将很乐意提供.