Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Temporary value is freed at the end of this statement [duplicate]

Tags:

I'm trying to scrape a webpage using the 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); } 

Which results in following error:

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 

I solved it by separating the .text() and .trim()

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

What is the difference? Why did the first attempt fail?

like image 838
mottosson Avatar asked Jan 05 '19 21:01

mottosson


1 Answers

This one seems convoluted at first, but remember that String and &str are different beasts.

String can live and be used on its own, but &str is just a reference to part of String. So, &str can live as long as referenced String lives. Lets see how it should work on return signatures.

let title_text = title   .text()   .trim(); //               ^       ^         ^ //               Node    String <- &str 
  1. Here, title is a select::Node.

  2. Node::text returns a String, but nothing binds it to context.

  3. String::trim, in turn, returns a &str which is a reference to part of String itself.

In the end, the borrow checker just doesn't understand how it should process a reference to String that will not live long enough in context, as it is a temporary value (non-bound).

like image 192
TSB99X Avatar answered Sep 21 '22 22:09

TSB99X