提问人:Jacob Runge 提问时间:11/2/2023 最后编辑:Jacob Runge 更新时间:11/2/2023 访问量:83
Rust 函数的返回值不能引用局部变量或临时变量
Return value from Rust function cannot reference local or temporary variable
问:
上下文
无法使此功能正常工作。我相信我理解错误试图告诉我什么,但我不明白我是如何犯错的/如何解决它们。
该函数是一个递归函数,它查看目录及其子目录并累积路径的向量和 Axum MethodRouter(我认为这与我面临的实际问题没有任何关系)。
错误
编译器错误指出“无法返回引用局部变量的值”。path
如果我替换为 ,错误就变成了“无法返回引用临时值的值”。path.to_str()
path.clone().to_str()
法典
fn assign_handlers(dir: Option<&str>) -> Vec<(&str, MethodRouter)> {
//Check root dir validity
let dir = match dir {
Some(s) => s,
None => return vec![],
};
//Look for routes in dir
let dir_path = fs::read_dir(dir).expect(&format!("Unable to access directory '{}'", &dir));
let mut routes = Vec::new();
for entry in dir_path {
match entry {
Ok(entry) => {
let path = entry.path();
if path.is_dir() {
//Recurse into subdirectories
let subroutes = assign_handlers(path.to_str());
for route in subroutes {
routes.push(route)
}
} else if path.is_file() {
// Cut for brevity (and because I don't know what goes here yet)
}
},
Err(_) => {},
}
}
routes
}
答:
Rust 是正确的。让我们解码 :表示它是引用,表示它是字符串的内容。在垃圾回收语言中,引用使对象保持活动状态,这很方便,但 Rust 做出了不同的选择,它通常更快、内存效率更高,并且可以用来查找编译器在其他语言中会让传递的许多错误:引用不会让对象保持活动状态。&str
&
str
编译器是这样告诉你的:根据定义,临时值是一旦你离开块就不再存在的值。由于您在函数中指定的返回类型包含 ,因此编译器信任您,并假定其中包含临时值,并且您正在尝试返回它们。由于无法返回临时值,因此会出现错误。&str
subroutes
所以,你应该做的是返回一些保证活着的东西。例如,这可以是 。除了,在这种情况下,你已经有一些活的东西:a - 相当于一个 ,除了它使用你的文件系统的编码,正如你的操作系统所要求的那样(许多语言混淆了 a 和 a - 这使得大多数用这些语言编写的应用程序在日本、韩国或中国无法使用,例如)。String
PathBuf
String
PathBuf
String
通过这些更改,您将获得:
fn assign_handlers(dir: Option<&Path>) -> Vec<(PathBuf, MethodRouter)> {
//Check root dir validity
let dir = match dir {
Some(s) => s,
None => return vec![],
};
//Look for routes in dir
let dir_path = fs::read_dir(dir).expect(&format!("Unable to access directory '{:?}'", &dir));
let mut routes = Vec::new();
for entry in dir_path {
match entry {
Ok(entry) => {
let path = entry.path();
if path.is_dir() {
//Recurse into subdirectories
let subroutes = assign_handlers(Some(&path));
for route in subroutes {
routes.push(route)
}
} else if path.is_file() {
}
},
Err(_) => {},
}
}
routes
}
另外,我不确定你为什么要通过.我建议只传递一个.这将稍微简化代码。Option<&PathBuf>
&PathBuf
评论
path
vec
&str
PathBuf
vec
path
path
dir
评论
Vec<String, MethodRouter>
entry.file_type().is_dir()
entry.path().is_dir()