我是相当新的生 rust ,我有一个问题,借检查。
我有这样一个函数:
impl<'a> DFA<'a> {
fn solve_next(&mut self, c: Option<char>) -> Option<TokenType> {
let node = self.state.unwrap_or_else(|| &self.start_node);
let checks: Vec<char> = node.connections.iter().map(|x| x.1).collect();
let mut position = None;
if let Some(c) = c {
position = checks.iter().position(|x| *x == c);
}
if let Some(i) = position {
let node = &node.connections[i].0;
self.state = Some(node);
None
} else {
if node.is_end {
return Some(TokenType::Keyword);
}
panic!("Invalid charter for current set");
}
}
}
此函数在循环完成时返回TokenType(枚举),在循环未完成时返回None。它位于此结构上:
struct DFA<'a> {
state: Option<&'a Node>,
start_node: Node,
}
节点为:
struct Node {
connections: Vec<(Node, char)>,
is_end: bool,
token_type: TokenType,
}
本发明的方法
fn insert(&mut self, _match: char, end: bool) -> &mut Node {
它创建并返回一个新节点,并将该节点添加到它自己连接中。
因此,当我想循环使用solve next函数时,我尝试:
impl<'a> Lexer<'a> {
fn next_char(&self) -> Option<char> {
let mut r: Option<char> = None;
for c in &self.chars {
match c {
' ' | '\n' | '\r' => {
continue;
}
_ => {
r = Some(c.clone());
break;
}
}
}
return r;
}
fn next_token(&'a mut self) {
let somechar = 'c';
let mut x = self.dfa.solve_next(self.next_char());
while let None = x {
x = self.dfa.solve_next(self.next_char());
}
}
}
该方法
struct Lexer<'a> {
//the output of the lexer
pub tokens: Vec<Token>,
chars: Vec<char>,
dfa: DFA<'a>,
}
编译错误是
error[E0499]: cannot borrow `self.dfa` as mutable more than once at a time
--> src/main.rs:177:17
|
146 | impl<'a> Lexer<'a> {
| -- lifetime `'a` defined here
...
175 | let mut x = self.dfa.solve_next(self.next_char());
| -------------------------------------
| |
| first mutable borrow occurs here
| argument requires that `self.dfa` is borrowed for `'a`
176 | while let None = x {
177 | x = self.dfa.solve_next(self.next_char());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
--> src/main.rs:177:37
|
146 | impl<'a> Lexer<'a> {
| -- lifetime `'a` defined here
...
175 | let mut x = self.dfa.solve_next(self.next_char());
| -------------------------------------
| |
| mutable borrow occurs here
| argument requires that `self.dfa` is borrowed for `'a`
176 | while let None = x {
177 | x = self.dfa.solve_next(self.next_char());
| ^^^^^^^^^^^^^^^^ immutable borrow occurs here
那么,我可以在这个循环中使用solve_next吗?因为我不知道如何创建一个函数,它可以像这样使用,而不需要一个可变的引用。
1条答案
按热度按时间inkz8wg91#
您的程式码实际发生的错误如下(playground):
这实际上是在抱怨对
self.start_node
的引用活得不够长,也就是说至少对'a
来说。原因是你的局部变量
node
,类型为&'x Node
,生存期为'x
,是self.state.unwrap()
和&self.start_node
的生存期中较短的一个。第一个是'a
,第二个是&self
的未命名生存期(从现在开始是's
)。但是根据Rust寿命规则,
'a
比DFA<'a>
长,Self
比's
长,并且Self
等于DFA<'a>
,那么我们得出'a
比's
长,所以局部node
的寿命实际上是's
.另一个关键词是:
因为
self.state
的类型是Option<&'a Node>
,这要求node
的生存期,也就是's
,比'a
长,但这是不可能的,我们已经确定它是相反的:'a
比's
存在更长时间。因此出现编译器错误。简而言之,你试图写一个自引用结构体,在一个字段中存储对另一个字段的引用,而这是众所周知的不可能的。
在您的问题的原始版本中,您试图通过向
solve_next()
函数添加额外的生存期来解决该问题:这样就强制
's
与'a
完全相等,所以这个函数的主体是正确的。不幸的是,如果你试图用以下语句调用它:失败原因:
原因与上述完全相同:
self
的匿名生存期必须比'a
长,但是编译器以相反的方式推导它。当然,您也可以用同样的方法 * 修复 * 它:
只要不尝试两次调用
solve_next()
,它就会编译。我不知道为什么调用
solve_next()
编译一次,但调用它两次都失败了。但实际上这并不重要,因为即使这个函数工作,使用这个额外的&'a mut self
,从外部代码调用这个函数仍然会有同样的问题。那么解决方案呢?我认为你需要重构代码,这样你就永远不会在同一个结构体中添加一个引用
start_node
。例如,您可以将
start_node
储存在这个结构之外:这样,并从
&'a self
中删除所有的生存期注解,它将只编译(playground)。