为什么变量的寿命不够长?

时间:2014-07-02 22:24:46

标签: rust object-lifetime lifetime

考虑这个应该返回给定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

enter image description here

错误信息很清楚,很遗憾我无法自己解决这个问题。我在理论上理解它,但对我来说还有一些模糊的东西。

我理解编译器想要告诉我,path_str的有效期不够长,因为返回值标有life 'a

但这就是它停止的地方:

  • 我理解对path(输入参数)的引用应该与str中包含的Option的引用完全一样长(输出)参数)

  • 因为我们返回Some(path_str.as_slice().slice_from(start))我认为实际上这意味着path_str只需path就可以生存。

我不明白的是为什么 path_str不能活得足够长,我该如何解决这个问题?是什么让它很快死去?

更新

正如评论中指出的那样,以及IRC删除超级as_slice()使得代码编译。有谁知道那是为什么?还有人指出,存在method直接获得扩展。但是,我真的对学习问题背后的故事更感兴趣。

1 个答案:

答案 0 :(得分:12)

这不是错误。这里的“问题”是as_slice的定义。它引用了它的参数,并返回一个与引用具有相同生命周期的&str,它无法反省它被调用的任何类型的内部生命周期。也就是说,只要数据path_str.as_slice()指向({1}},&str就会返回path_str,持续时间为path_str Path)。

换句话说,这里有两个生命周期。我将在@ Arjan的filed bug示例中使用假设的块生命周期注释语法(此答案基于my response there)。

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电话。但是,使用dynamically sized types (DST),我们可以写impl StrSlice for str,然后slice.as_slice() 返回&'a str,因为不会是一个额外的引用层(即self: &'a str)。

相关问题