jdn*_*njd 2 types pointers lifetime dereference rust
我正在尝试实现一个函数,以将包含模式的所有字符串的向量从(Vec<String>)返回到另一个Vec<String>。
这是我尝试的:
fn select_lines(pattern: &String, lines: &Vec<String>) -> Vec<String> {
let mut selected_lines: Vec<String> = Vec::new();
for line in *lines {
if line.contains(pattern) {
selected_lines.push(line);
}
}
selected_lines
}
Run Code Online (Sandbox Code Playgroud)
导致在for循环的行上出现错误(*行)。我是Rust的新手(昨天开始学习Rust!),现在对解决该错误几乎一无所知。
我可以删除,*并且该错误消失了,但是有关类型不匹配的错误开始达到高潮。我想保持功能的签名完整。有办法吗?
问题是,你想移动的所有权String情况下出去您的lines参数(这是一个输入参数)...过户到返回值(输出)。
有几个选项供您选择。
Clone对您来说最简单的方法就是将这些行克隆出来:
selected_lines.push(line.clone());
Run Code Online (Sandbox Code Playgroud)
既然您已经克隆了行,那么就没有所有权问题了。您要返回的是向量中s的新实例String。它们只是您传递的副本的副本。
另一个选择(避免多余的分配)是让编译器知道您将不返回任何悬空的引用:
// introduce a lifetime to let the compiler know what you're
// trying to do. This lifetime basically says "the Strings I'm returning
// in the vector live for at least as long as the Strings coming in
fn select_lines<'a>(pattern: &String, lines: &'a Vec<String>) -> Vec<&'a String> {
let mut selected_lines: Vec<&String> = Vec::new();
for line in lines {
if line.contains(pattern) {
selected_lines.push(line);
}
}
selected_lines
}
Run Code Online (Sandbox Code Playgroud)
这就是解决当前问题的方法。
如果我要写这个,我会稍作修改。这是另一个旋转:
fn select_lines<I>(pattern: I, lines: &[I]) -> Vec<&str>
where
I: AsRef<str>,
{
let mut selected_lines: Vec<&str> = Vec::new();
for line in lines {
if line.as_ref().contains(pattern.as_ref()) {
selected_lines.push(line.as_ref());
}
}
selected_lines
}
Run Code Online (Sandbox Code Playgroud)
您可以将此版本与Strings或&strs,向量或切片一起使用。
let lines = vec!["Hello", "Stack", "overflow"];
let selected = select_lines("over", &lines);
// prints "overflow"
for l in selected {
println!("Line: {}", l);
}
let lines2 = [String::from("Hello"), String::from("Stack"), "overflow".into()];
let selected2 = select_lines(String::from("He"), &lines2);
// prints "Hello"
for l in selected2 {
println!("Line again: {}", l);
}
Run Code Online (Sandbox Code Playgroud)