【问题标题】:Temporary value is freed at the end of this statement [duplicate]临时值在此语句的末尾被释放 [重复]
【发布时间】:2019-06-01 01:09:35
【问题描述】:

我正在尝试使用 Select crate 抓取网页:

let document = Document::from_read(response).unwrap();

for node in document.find(Class("lia-list-row")) {
    let title = node.find(Class("page-link")).next().unwrap();
    let title_text = title.text().trim();

    println!("{}\n", title_text);
}

这会导致以下错误:

let title_text = title.text().trim();
                 ^^^^^^^^^^^^       - temporary value is freed at the end of this statement
                 |
                 creates a temporary which is freed while still in use

println!("{} - {}\n", i, title_text);
                         ---------- borrow used here, in later iteration of loop

我通过分离 .text().trim() 解决了这个问题

let title_text = title.text();
let trim_text = title_text.trim();

有什么区别?为什么第一次尝试失败了?

【问题讨论】:

标签: rust borrow-checker


【解决方案1】:

这个一开始看起来很复杂,但请记住 String&str 是不同的野兽。

String 可以独立存在和使用,但&str 只是对String 的一部分的引用。因此,&str 可以与引用的 String 一样长。让我们看看它应该如何处理返回签名。

let title_text = title   .text()   .trim();
//               ^       ^         ^
//               Node    String <- &str
  1. 这里,titleselect::Node

  2. Node::text 返回一个String,但没有将其绑定到上下文。

  3. String::trim 反过来返回一个 &amp;str,它是对 String 本身的一部分的引用。

最后,借用检查器只是不明白它应该如何处理对 String 的引用,因为它是一个临时值(非绑定),因此在上下文中不会存在足够长的时间。

【讨论】:

  • 有没有办法在不声明新变量的情况下解决这个问题?
  • @rm.rf.etc 你可以使用title.text().trim().to_string(),如果你允许复制的话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-05
  • 1970-01-01
  • 2013-09-06
  • 2019-11-06
  • 2012-12-16
相关资源
最近更新 更多