【问题标题】:Temporary value is freed inconsistency临时值被释放不一致
【发布时间】:2019-11-30 20:03:56
【问题描述】:

为什么会产生“临时值被释放”的错误:

    let mut new_string = String::from("test");
    new_string.push_str(
        if true { &format!("{}","ay") } else { "ay" }
    );

当这是有效的:

    let mut new_string = String::from("test");
    new_string.push_str(
        &format!("{}","ay")
    );

游乐场Link

【问题讨论】:

  • 临时生命周期为specified to some extent in the Rust reference。在这种特殊情况下,引用并不完全清楚,但从编译器的行为来看,format!() 返回的临时值在第一种情况下一直存在到 block 结束,而在第二种情况下,它会一直持续到 push_str() 调用结束。第一种情况下的“块”只是 if 表达式的“then”分支。
  • 参考中的措辞听起来像是临时的应该在第一种情况下存活更长的时间,但是:“块的尾部表达式被认为是包含块的语句的一部分”
  • 好吧,这很有道理......但是为什么这会起作用:new_string.push_str( {&format!("{}","ay")} );
  • 我认为这个参考有点太模糊,无法完全理解临时生命周期。我找到了更完整的解释in this issue。那里解释的“竞技场树”确实似乎与您提到的所有情况下观察到的行为完全一致。

标签: rust


【解决方案1】:

format! 返回一个String(没有&),因此您可以拥有它返回的内容。你可以说当前块拥有它。然后将其放在当前块的末尾。

let mut new_string = String::from("test");
new_string.push_str(
    if true { &format!("{}","ay") } else { "ay" }
);

这是{ &format!("{}","ay") }。在} 处,该值在push_str 可以使用之前被删除。

let mut new_string = String::from("test");
new_string.push_str(
    &format!("{}","ay")
);

它的寿命足够长。

new_string.push_str( {&format!("{}","ay")} ); 有效,因为花括号已被优化掉。

new_string.push_str( {
    let t = &format!("{}","ay");
    t
} );

不工作。

【讨论】:

    猜你喜欢
    • 2019-06-01
    • 1970-01-01
    • 2011-10-28
    • 1970-01-01
    • 2012-02-27
    • 2021-11-03
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    相关资源
    最近更新 更多