我使用Rust实现编译器作为学习练习的一部分。对于编译器的部分,我实现了令牌偷看以执行有效的解析器交替。要在Rust中执行此操作,我会查看令牌堆栈,然后匹配令牌,这会产生如下所示的嵌套匹配语句。
// Is there an optional type modifier
// Peek at the next token and process it
match tokens.last() {
Some(token) =>
match token.clone() {
lexer::Token::OpenBracket => {
tokens.pop()
},
_ => ()
},
None => ()
};
我无法确定适当的借用检查逻辑,以便将tokens
向量作为可变引用传递给最内层范围。我已经使用可变引用在匹配语句中尝试了重新绑定tokens
的变体,但编译器仍然将tokens
捕获为不可变的。如何在此示例中获得对最内部作用域的可变tokens
引用?
答案 0 :(得分:1)
如果克隆令牌无关紧要,可以使用Option::cloned
let last = tokens.last().cloned();
if let Some(token) = last {
match token {
lexer::Token::OpenBracket => {
tokens.pop();
},
_ => ()
}
}
通过克隆内容(从而删除引用,即无法借用向量),您可以再次借用向量。
如果您不想克隆,可以随时执行此操作:
let mut must_pop = false;
if let Some(token) = tokens.last() {
match token {
lexer::Token::OpenBracket => {
must_pop = true;
},
_ => ()
}
}
if must_pop {
tokens.pop();
}
这种解决方案不是很“美观”,但至少可以起作用。