【问题标题】:why do I need to use `let` binding [duplicate]为什么我需要使用`let`绑定[重复]
【发布时间】:2022-01-07 13:51:58
【问题描述】:

在尝试打印我的主目录时遇到以下错误:

fn main() {
    let home = home::home_dir().unwrap().to_str().unwrap();
    println!("home dir: {}", home);
}
error[E0716]: temporary value dropped while borrowed
 --> src/main.rs:3:16
  |
3 |     let home = home::home_dir().unwrap().to_str().unwrap();
  |                ^^^^^^^^^^^^^^^^^^^^^^^^^                  - temporary value is freed at the end of this statement
  |                |
  |                creates a temporary which is freed while still in use
4 |     println!("home dir: {}", home);
  |                              ---- borrow later used here
  |
  = note: consider using a `let` binding to create a longer lived value

但是如果我拆分错误消息中带下划线的部分并将其放入单独的变量中,它会起作用:

fn main() {
    let home_buf = home::home_dir().unwrap();
    let home_str = home_buf.to_str().unwrap();
    println!("home dir: {}", home_str);
}

我的问题是这两个例子有什么区别?
(我在我的代码中使用home crate

【问题讨论】:

  • 编译器报错信息的哪一部分不清楚?
  • 附带问题:home 在原始示例中显然意味着两个不同的事物这一事实是否也会引起问题?看起来既是板条箱名称又是变量名称。
  • 这是个好问题。我认为变量名会影响 crate,但我尝试在下一行使用 home::home_dir() 并且效果很好。
  • @KevinAnderson 没问题,Rust 能够消除两者之间的歧义。

标签: rust


【解决方案1】:

home::home_dir().unwrap() 提供std::path::PathBuf。 调用.to_str().unwrap() 提供了对存储在前面PathBuf 中的内容的引用。 因此,为了使引用有效,PathBuf 必须存在(Rust 强制执行)。

在您的第一个表达式中,PathBuf 是一个临时的,将被立即删除;参考home 将悬空! (这是一个错误)。

在您的第二个示例中,home_buf 绑定使PathBuf 保持活动状态,那么只要存在home_buf,就可以使用引用home_str

【讨论】:

    【解决方案2】:

    另一种看待它的方式是,您的原始代码大致相当于:

    fn main() {
        let home;
        {
            let tmp1: Option<PathBuf> = home::home_dir();
            let tmp2: PathBuf = tmp1.unwrap();
            let tmp3: Option<&str> = tmp2.to_str();
            home = tmp3.unwrap();
        }
        println!("home dir: {}", home);
    }
    

    换句话说,由表达式创建的所有临时值的持续时间与表达式一样长,并且不会长于该表达式。不允许将从 tmp2 借用的 reference 存储到 home 中,因为这样引用的寿命将超过它借用的值。

    通过引入一个变量来保存PathBuf,您使它的持续时间比表达式更长,并且引用变得有效。

    【讨论】:

      猜你喜欢
      • 2012-03-08
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 2013-06-02
      • 1970-01-01
      • 2013-12-17
      • 2014-06-12
      • 2014-06-20
      相关资源
      最近更新 更多