提问人:Kodra 提问时间:10/12/2023 更新时间:10/12/2023 访问量:56
如何正确返回对临时值的引用?
How to correctly return a reference to temporary value?
问:
例如,此函数按预期工作:
fn get_suffix(str: Option<&str>) -> u32 {
str.and_then( |s| s.rsplit('_').next() )
.and_then( |s| s.parse::<u32>().ok() )
.unwrap_or(0)
}
但这给了我编译错误:
fn get_suffix_from_path(path: &Path) -> u32 {
path.file_stem()
.and_then( |s| s.to_string_lossy().rsplit('_').next() )
.and_then( |s| s.parse::<u32>().ok() )
.unwrap_or(0)
}
328 | stem.to_string_lossy().rsplit('_').next())
| ----------------------^^^^^^^^^^^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| temporary value created here
我不完全确定这意味着什么。它是否是由关闭结束时会立即丢弃的事实造成的?解决这个问题的惯用方法是什么?to_string_lossy()
String
我试过了这个:
stem.to_string_lossy().rsplit('_').next().and_then(|s| Some(s.to_owned()) )
它有效,但它不仅丑陋,而且不必要地复制了字符串。
答:
2赞
prog-fh
10/12/2023
#1
你是对的:在你解析其内容并获得整数之前,提供的必须存在。Cow<str>
.to_string_lossy()
您只需要在存在此漏洞的闭包内执行解析即可。Cow<str>
use std::path::Path;
fn get_suffix_from_path(path: &Path) -> u32 {
path.file_stem()
.and_then(|s| {
s.to_string_lossy()
.rsplit('_')
.next()
.and_then(|s| s.parse().ok())
})
.unwrap_or(0)
}
fn main() {
let p = Path::new("/tmp_56");
let s = get_suffix_from_path(&p);
println!("{:?} {:?}", p, s);
}
/*
"/tmp_56" 56
*/
0赞
Rasmus Kaj
10/12/2023
#2
你是对的,在你的示例中,“额外”副本实际上是必需的(你可以字符串化和修改to_string_lossy返回的 Cow,使其只有一个副本,而不是两个副本)。
如果奶牛是借来的或拥有的,你也可以打开,并归还一头奶牛,该奶牛要么是子借用的,要么是对拥有的字符串的修改。但这变得相当复杂。
在大多数情况下,您也可以选择仅支持 utf-8 路径,并使用 path.to_str(),然后将其解包(在非 utf8 路径上引起恐慌)或以其他方式将其作为错误处理。
评论