在使用迭代器时,我经常遇到 Rust 中旧的
temporary value dropped while borrowed
错误,特别是当迭代器超过 &str
或 String
时。或者,当我从某个文件中读取时,会发生这种情况。通常,您可以通过定义一个 var 来拥有临时值来解决问题:
示例:
fn main() {
let s = Some("a".to_string());
let s: &str = s.unwrap().as_str();
dbg!(s);
}
抛出错误,因为没有 var 拥有
unwrap
中的字符串。简单的解决方案是:
fn main() {
let s = Some("a".to_string());
let temp: String = s.unwrap()
let s: &str = temp.as_str();
dbg!(s);
}
但这让我很恼火。这种情况相对不现实,但是当使用 iters 时,你确实会遇到这个问题。当您遇到这种情况时,您必须中断整个迭代器链才能保存临时值。在我看来,编写这段代码的更简洁的方法是:
fn main() {
let s = Some("a".to_string());
let s: &str = s.unwrap().define!().as_str();
dbg!(s);
}
这使用了虚构的宏
define!
。理论上,这个宏可以作为一种方法宏,它将句点左侧的类型作为参数
当改写为当前的宏语法时,它看起来像这样:
let s: &str = define!(s.unwrap()).as_str();
尽管我不是宏专家,但当前的宏类型可能可以实现此宏。这两个宏都可以扩展到类似这样的东西
let __temp_s = s.unwrap();
let s: &str = __temp_s.as_str();
它可能仍然存在问题,因为它必须适合
let s: &str =
部分之后,因为它无法扩展到其调用站点之外。
老实说,我只是想摆脱在做其他事情的过程中定义一个新的 var 所带来的小不便(或者必须转到表达式的开头才能在整个表达式上调用宏)。这只是我每天处理的一些编译器战斗。 我非常想听听您是否对当前的 Rust 有任何想法(或者我的问题是否有意义)!
一般来说,如果您要移出变量,然后引用结果,则只需创建一个临时变量即可。但在这种情况下,有
let s = s.as_deref().unwrap();
,它会切换引用获取和展开的顺序,以便您不依赖于拥有的但临时的展开结果。