平衡支架时的寿命问题
Lifetime issues while balancing brackets
我面临生命周期的问题。实现应该平衡三种括号:(
、[
和 {
。我正在为此使用堆栈,但 运行 遇到了一些问题。
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
s 来解决,但它似乎不必要地昂贵,我真的很想看到解决这个问题的方法..
您似乎混淆了字符串文字 "("
和 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
).
至于后续问题
say we have a stack with string slices, how can one deal with the lifetime issues
嗯,这完全取决于为什么需要保存字符串(我们已经看到没有必要)。
由于尝试存储对临时字符串的引用(代码中的 c.to_string()
),因此您可以存储拥有的 String
(无论如何您已经分配了它们) ).
我面临生命周期的问题。实现应该平衡三种括号:(
、[
和 {
。我正在为此使用堆栈,但 运行 遇到了一些问题。
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
s 来解决,但它似乎不必要地昂贵,我真的很想看到解决这个问题的方法..
您似乎混淆了字符串文字 "("
和 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
).
至于后续问题
say we have a stack with string slices, how can one deal with the lifetime issues
嗯,这完全取决于为什么需要保存字符串(我们已经看到没有必要)。
由于尝试存储对临时字符串的引用(代码中的 c.to_string()
),因此您可以存储拥有的 String
(无论如何您已经分配了它们) ).