rust - 回归自我以避免搬出借用内容
问题描述
我正在尝试在 Rust 中实现 Monkey 玩具语言。我现在正在尝试生成和 AST,但在此之前,我需要有一个正常运行的解析器。我已经有了我的词法分析器。
所以我的解析器的相关部分如下所示:
struct Parser<'a> {
lexer: lexer::Lexer<'a>,
current_token: Token<'a>,
peek_token: Token<'a>,
}
impl<'a> Parser<'a> {
// Create a new parser.
// Depends on a lexer capable of iterating over
// the tokens.
pub fn new(mut lexer: lexer::Lexer<'a>) -> Parser {
// constructor
}
// Read the next token.
//
// Returns self to avoid weird `move out of
// borrowed content` issue?
fn next_token(mut self) -> Self {
self.current_token = self.peek_token;
self.peek_token = self.lexer.next_token();
self
}
}
问题出在next_token
功能上。我真的很希望它可以与借来的 一起使用&self
,如下所示:
// Read the next token.
fn next_token(&mut self) {
self.current_token = self.peek_token;
self.peek_token = self.lexer.next_token();
}
但是编译器抱怨移出借来的内容。现在,我明白为什么会发生这种情况了:我只是在借self
,我不能执行从self.peek_token
to的迁移,self.current_token
因为我不拥有它。
不过,我的问题是,回归Self
是最好的策略吗?返回的代码Self
工作正常,但界面变得非常非常难看。
#[test]
fn test_next_token() {
let l = lexer::Lexer::new("let answer = 42;");
let p = Parser::new(l);
assert_eq!(p.current_token, Token::Let);
let p = p.next_token();
assert_eq!(p.current_token, Token::Ident("answer"));
}
有没有我没有看到的替代方案?这是 Rust 中的常见习语吗?
这是游乐场的链接。
解决方案
您可以使用std::mem::replace
:
use std::mem;
// Read the next token.
fn next_token(&mut self) {
self.current_token = mem::replace(&mut self.peek_token, self.lexer.next_token());
}
replace
将第二个参数存储到第一个参数中,并返回第一个参数的当前值,然后我们将其分配给current_token
.
推荐阅读
- nuxt.js - 在 CapacitorJS 编译的应用程序中加载动态图像时出错
- c# - Jwt Bearer Authentication 中间件始终将 User.Identity.IsAuthenticated 设置为 false
- r - 如何使用 kableextra 绘制的表格中的文本居中?
- java - Java 中的泛型(队列)
- package - 与 `react-transition-group` 包类似,但对于苗条?
- python - 如何从包含超过 7 个唯一字符的列表中删除字符串?
- laravel - Laravel 存储框架允许的源路径类型和格式
- ios - 如何在颤振中自动设置像苹果这样的图像处理
- oracle - 更新列特定触发器的最佳实践
- javascript - 如何减少两个 React-Native-Elements 之间的边距 - React Native