Writing a function to find the corresponding value to a given query name as an argument out of url, I got an error following:
error[E0515]: cannot return value referencing local variable `url`
--> src/main.rs:55:25
|
51 | let mut queries = url.query_pairs();
| ----------------- `url` is borrowed here
...
55 | Some((_, value)) => value
| ^^^^^ returns a value referencing data owned by the current function
code:
use url::{self, Url};
fn find_query(referer: String, query_name: &str) -> Cow<str> {
let url_text = Url::parse(&referer).unwrap();
let mut queries = url_text.query_pairs();
let index_of_name = queries.find(|(key,_)| key == query_name);
let result = match index_of_name {
None => panic!("name didn't match any"),
Some((_, value)) => value
};
result
}
Although I fixed it with the modification below, I still don't see why I had this type of error even though result itself was not borrowed. The message in the error "returns a value referencing data owned by the current function" sounds right.
Can anyone break down the reason behind this error?
Thank you in advance.
fixed code:
use url::{self, Url};
fn find_query(referer: String, query_name: &str) -> String {
let url_text = Url::parse(&referer).unwrap();
let queries = url_text.query_pairs();
let index_of_name = queries.into_owned().find(|(key,_)| key == query_name);
let result = match index_of_name {
None => panic!("name didn't match any"),
Some((_, value)) => value
};
result
}
CodePudding user response:
Writing:
let url: Url = todo!();
url.query_pairs()
is the same as writing:
let url: Url = todo!();
Url::query_pairs(&url) // notice the borrow of url here
This is referred to as "unified function call syntax". Really, it's the foo.bar() syntax that is special, and Foo::foo(bar) is the "default" syntax.
You can also tell this is happening by looking at the function signature of query_pairs:
impl Url {
pub fn query_pairs(&self) -> Parse<'_> {
// ...
}
}
The &self parameter denotes that this function takes the struct it is called on by immutable reference.
Hopefully this should illustrate why the call to into_owned() fixed the error
