rust - 在将元素插入 Vec 时借用时临时值(value)下降

标签 rust borrow-checker

我正在尝试解决 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因为inputinputs 中元素的引用,还有你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/

相关文章:

rust - 如果不是为了对象安全,Rust 的哪些安全保证会丢失?

rust - 从向量获取特征对象引用

rust - 请求消息值必须在静态生命周期内有效

Rust:将值移出选项并压入堆栈

reference - 为什么我不能从闭包中返回对外部变量的可变引用?

rust - 从从 JSON 加载的 Vec<(String, String)> 创建 Petgraph 图

HashSet 作为其他 HashSet 的键

rust - 为什么代码编译需要这些确切的生命周期?

rust - 无法从 &mut self 借用文件(错误消息 : cannot move out of borrowed content)

multithreading - 使用Mutex防止同时处理同一类型时进行多线程列表迭代