As a Rust learner it is important to know the differences between strings (String) and string slices (&str), and how those two types interact.
The lines() method of an &str returns the lines as iterator over &str, which is the same type.
However the lines method of a string also returns an iterator over &str, which is the same type as before but in this case not the same type as the input.
This means, your output will be of type Vec<&str>.
However in that case you need a lifetime because otherwise you can't return a reference. In this case your example would look like this:
fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents.lines().filter(|line| line.contains(query)).collect()
}
fn main() {
println!("found: {:?}",search("foo", "the foot\nof the\nfool"));
}
However if you want the vector to contain strings, you can use the to_owned()
function to convert a &str into a String:
fn search(query: &str, contents: &str) -> Vec<String> {
contents.lines().map(|line| line.to_owned()).filter(|line| line.contains(query)).collect()
}
fn main() {
println!("{:?}",search("foo", "the foot\nof the\nfool"));
}
However this is inefficient because some strings are created that aren't used so it is better to map last:
fn search(query: &str, contents: &str) -> Vec<String> {
contents.lines().filter(|line| line.contains(query)).map(|line| line.to_owned()).collect()
}
fn main() {
println!("{:?}",search("foo", "the foot\nof the\nfool"));
}
Or with contents
of type String, but I think this doesn't make much sense:
fn search(query: &str, contents: String) -> Vec<String> {
contents.lines().map(|line| line.to_owned()).filter(|line| line.contains(query)).collect()
}
fn main() {
println!("{:?}",search("foo", "the foot\nof the\nfool".to_owned()));
}
Explanation: Passing contents
as a String
isn't very useful because the search function will own it, but it is not mutable, so you can't change it to the search result, and also your search result is a vector, and you can't transform a single owned String into multiple owned ones.
P.S.: I'm also relatively new to Rust, so feel free to comment or edit my post if I missed something.