[英]Why does the variable not live long enough?
考虑应该返回给定Path
的文件扩展名的此函数。
pub fn get_extension<'a>(path: &'a Path) -> Option<&'a str> {
let path_str = path.as_str().unwrap();
let ext_pos = regex!(".[a-z0-9]+$").find(path_str);
match ext_pos {
Some((start, _)) => {
return Some(path_str.as_slice().slice_from(start))
},
None => return None
}
}
错误消息如下:
`path_str` does not live long enough
错误信息很清楚,很遗憾我无法自己解决这个问题。 我在理论上理解它,但对我来说还有一些模糊的东西。
据我所知,编译器要告诉我, path_str
不活足够长的时间要与标有终身的返回值有效的'a
。
但这就是它停止的地方:
我理解对path
(输入参数)的引用应该与对包含在Option
的str
的引用(输出参数)完全一样长
因为我们返回Some(path_str.as_slice().slice_from(start))
我假设在实践中这意味着path_str
需要和path
一样长。
我不明白的是为什么 path_str
不能长寿,我怎么能解决这个问题呢? 是什么让它很快死去?
UPDATE
正如在评论和IRC中指出的那样,删除as_slice()
会使代码编译。 有谁知道那是为什么? 还有人指出存在一种直接获得扩展的方法 。 但是,我实际上更感兴趣的是学习问题背后的故事。
这不是一个错误。 这里的“问题”是as_slice
的定义。 它引用了它的参数,并返回一个&str
引用具有相同生命周期的&str
,它无法反省它被调用的任何类型的内部生命周期。 也就是说, path_str.as_slice()
返回一个&str
,其持续时间与path_str
一样长, 而不是数据path_str
指向(原始Path
)。
换句话说,这里有两个生命周期。 我将在@ Arjan 提交的bug的例子中使用假设的块生命周期注释语法(这个答案基于我在那里的回复 )。
fn test<'a>(s: &'a String) -> &'a str {
'b: {
let slice: &'a str = s.as_slice();
slice.as_slice()
}
}
对于第二个as_slice
调用,我们有self: &'b &'a str
,因此它返回&'b str
,这太短了: 'b
只是本地test
。
正如您所发现的,现在修复只是删除无关的as_slice
调用。 但是,对于动态大小的类型(DST) ,我们将能够impl StrSlice for str
编写impl StrSlice for str
,然后slice.as_slice()
将返回一个&'a str
,因为不会有额外的引用层(是, self: &'a str
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.