我正在尝试解决 RPN calculator练习但偶然发现了这个temporary value dropped while borrowed
我似乎无法解决的错误。
这是我的代码:
#[derive(Debug)]
pub enum CalculatorInput {
Add,
Subtract,
Multiply,
Divide,
Value(i32),
}
pub fn evaluate(inputs: &[CalculatorInput]) -> Option<i32> {
let mut stack = Vec::new();
for input in inputs {
match input {
CalculatorInput::Value(value) => {
stack.push(value);
},
operator => {
if stack.len() < 2 {
return None;
}
let second = stack.pop().unwrap();
let first = stack.pop().unwrap();
let result = match operator {
CalculatorInput::Add => first + second,
CalculatorInput::Subtract => first - second,
CalculatorInput::Multiply => first * second,
CalculatorInput::Divide => first / second,
CalculatorInput::Value(_) => return None,
};
stack.push(&result.clone());
}
}
}
if stack.len() != 1 {
None
} else {
Some(*stack.pop().unwrap())
}
}
我得到的错误:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:32:29
|
32 | stack.push(&result.clone());
| ^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
...
36 | if stack.len() != 1 {
| ----- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
如果我理解正确的话,变量result
在 for 循环之外(实际上在运算符匹配分支之外)没有记录器,这就是我克隆它的原因,但它仍然给我同样的错误。
如何复制堆栈 Vec 所拥有的结果(如果这是我应该做的)?
仅供引用,如果有人认为这有用,这是考虑到收到的所有帮助后的最终解决方案:
use crate::CalculatorInput::{Add,Subtract,Multiply,Divide,Value};
#[derive(Debug)]
pub enum CalculatorInput {
Add,
Subtract,
Multiply,
Divide,
Value(i32),
}
pub fn evaluate(inputs: &[CalculatorInput]) -> Option<i32> {
let mut stack: Vec<i32> = Vec::new();
for input in inputs {
match input {
Value(value) => {
stack.push(*value);
},
operator => {
if stack.len() < 2 {
return None;
}
let second: i32 = stack.pop().unwrap();
let first: i32 = stack.pop().unwrap();
let result: i32 = match operator {
Add => first + second,
Subtract => first - second,
Multiply => first * second,
Divide => first / second,
Value(_) => return None,
};
stack.push(result);
}
}
}
if stack.len() != 1 {
None
} else {
stack.pop()
}
}
无需克隆,因为 i32 实现了 Copy 特征。
问题是我的 vec 收到了 &i32
而不是i32
,因此 Rust 将其推断为 Vec<&i32>
.
最佳答案
错误是因为 Rust 没有推断出您期望的类型。
在您的代码中,value
的类型推断为 &i32
因为input
是 inputs
中元素的引用,还有你push
一个value
稍后,因此类型为 stack
推断为 Vec<&i32>
.
最好的解决方法是显式指定堆栈类型:
let mut stack: Vec<i32> = Vec::new();
因为i32
已实现Copy
特征,你永远不需要克隆 i32
值,如果是引用,则取消引用它。
固定代码:
#[derive(Debug)]
pub enum CalculatorInput {
Add,
Subtract,
Multiply,
Divide,
Value(i32),
}
pub fn evaluate(inputs: &[CalculatorInput]) -> Option<i32> {
let mut stack: Vec<i32> = Vec::new();
for input in inputs {
match input {
CalculatorInput::Value(value) => {
stack.push(*value);
}
operator => {
if stack.len() < 2 {
return None;
}
let second = stack.pop().unwrap();
let first = stack.pop().unwrap();
let result = match operator {
CalculatorInput::Add => first + second,
CalculatorInput::Subtract => first - second,
CalculatorInput::Multiply => first * second,
CalculatorInput::Divide => first / second,
CalculatorInput::Value(_) => return None,
};
stack.push(result);
}
}
}
if stack.len() != 1 {
None
} else {
Some(stack.pop().unwrap())
}
}
关于rust - 在将元素插入 Vec 时借用时临时值(value)下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70579664/