我正面临一生的问题。实现应平衡三种括号:(
,[
和{
。我为此使用了堆栈,但是遇到了一些问题。
pub struct Brackets {
stack: Vec<char>,
}
impl<'a> From<&'a str> for Brackets {
fn from(input: &str) -> Self {
let mut stack: Vec<char> = Vec::new();
for c in input.chars() {
stack.push(c);
}
Brackets { stack }
}
}
impl<'a> Brackets {
pub fn are_balanced(&self) -> bool {
let mut stack = Vec::new();
for c in &self.stack {
// Converts the character to a String to a &str... Feels dumb
let slice = &c.to_string()[..];
match slice {
"(" | "[" | "{" => stack.push(slice),
")" | "]" | "}" => {
let popped = stack.pop();
match popped {
Some(")") => {
if slice != "(" {
return false;
};
}
Some("]") => {
if slice != "[" {
return false;
};
}
Some("}") => {
if slice != "{" {
return false;
};
}
_ => return false,
}
}
_ => continue,
}
}
true
}
}
我想推开一个括号,然后弹出一个闭括号。如果右方括号与右方括号不匹配,则这些括号不平衡。我忽略的任何非括号输入。
我遇到的问题:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:21:26
|
21 | let slice = &c.to_string()[..];
| ^^^^^^^^^^^^^ temporary value does not live long enough
...
47 | }
| - temporary value dropped here while still borrowed
...
50 | }
| - temporary value needs to live until here
我知道are_balanced(&self)
函数中的堆栈比我要推入堆栈的slice
变量的寿命更长。我该如何解决?我尝试将堆栈的类型更改为&'a str
,并在Brackets
结构上添加了生命周期,但没有成功。一种猜测是可以通过在各处使用拥有的String
来解决,但这似乎不必要,而且我真的很想看到解决方案。
答案 0 :(得分:4)
您似乎将字符串文字"("
与char
文字'('
混淆了。如果替换所有字符串文字,则代码可以正常工作
for &c in &self.stack {
match c {
'(' | '[' | '{' => stack.push(c),
')' | ']' | '}' => {
let popped = stack.pop();
match popped {
Some(')') => {
if c != '(' {
return false;
};
}
Some(']') => {
if c != '[' {
return false;
};
}
Some('}') => {
if c != '{' {
return false;
};
}
_ => return false,
}
}
_ => continue,
}
}
Rust与Python或Bash不同,char
和字符串的类型不同。但是,这有点误导,因为它实际上并不表示字符,而是Unicode标量值。您认为某个字符的某些内容实际上无法用char
来表示(例如,许多表情符号,或诸如ɔ̃
之类的强调字母)。这意味着您可能需要三思而后行在某些应用程序中使用char
还是字符串。但是,出于平衡括号的目的,最好使用char
;我不希望甚至花哨的Unicode括号都没有自己的标量值。
请注意,我也已将循环更改为使用&c
,这是因为迭代堆栈会产生对其元素的引用(在我们的情况下为&char
),但是这样做有点不方便案件。使用&c
可以确保c
本身就是char
(&c: &char
<=> c: char
)。
关于后续问题
假设我们有一个包含字符串切片的堆栈,那么如何处理生命周期问题
好吧,这将完全取决于为什么需要保存字符串(我们认为没有必要)。
由于问题来自尝试存储对临时字符串的引用(代码中的c.to_string()
),因此您可以存储拥有的String
(而是已经分配了它们)。