为什么变量的寿命不足

为什么变量的寿命不足

本文介绍了为什么变量的寿命不足?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑此函数,该函数应返回给定Path的文件扩展名.

Consider this function that should return the file extension of a given 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

错误消息非常清楚,很遗憾我不能自己解决.我从理论上理解它,但对我来说仍然有一些模糊的东西.

The error message is pretty clear and it's a shame I can't work it out on my own. I understand it in theory but there are still a couple of blurred things for me.

我了解编译器想告诉我path_str的生存期不足以使其有效,因为带有生命周期'a的返回值标记为.

I understand that the compiler wants to tell me that path_str does not live long enough to be valid as the return value with is marked with lifetime 'a.

但是这对我而言止于此:

But this is where it stops for me:

  • 我了解对path的引用(输入参数)的寿命应与对包裹在Optionstr引用(输出参数)的寿命完全一样长

  • I understand that the reference to path (the input parameter) should life exactly as long as the reference to the str that is wrapped in the Option (the output parameter)

因为我们返回了Some(path_str.as_slice().slice_from(start)),所以我认为在实践中这意味着path_str的寿命必须与path一样长.

since we return Some(path_str.as_slice().slice_from(start)) I assume that in practice that means that path_str needs to live as long as path.

我不明白的是为什么准确?path_str的寿命不够长,我该如何解决?是什么让它很快死掉?

What I don't understand is why exactly does path_str not live long enough and how could I fix this? What makes it die to soon?

更新

删除多余的as_slice()可使代码编译.有人知道为什么吗?还指出,存在方法直接获取扩展名.但是,是的,尽管如此,我实际上对学习问题背后的故事更感兴趣.

As pointed out in the comments and also on IRC removing the superflous as_slice() makes the code compile. Does anyone know why that is? It was also pointed out that there exists a method to get the extension directly. But yep, I'm actually more interested in learning the story behind the problem though.

推荐答案

这不是错误.这里的问题"是 as_slice 的定义.它接受对其参数的引用,并返回一个与 reference 相同的生存期的&str,它不能自省其被调用的任何类型的内部生存期.也就是说,path_str.as_slice()返回的&str持续时间与path_str相同,而不是,只要数据path_str指向(原始Path).

This isn't a bug. The "problem" here is as_slice's definition. It takes a reference to its arguments, and returns a &str with the same lifetime as the reference, it can't introspect into the internal lifetimes of whatever type it is being called on. That is, path_str.as_slice() returns a &str that lasts for as long as path_str, not as long as the data path_str points at (the original Path).

换句话说,这里有两个生命.我将在@Arjan的提交的错误的示例中使用假设的块寿命注释语法基于我的回复).

In other words, there's two lifetimes here. I'll use a hypothetical block-lifetime annotation syntax on the example from @Arjan's filed bug (this answer is based of 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的本地.

For the second as_slice call we have self: &'b &'a str, and thus it returns &'b str, which is too short: 'b is just local to test.

正如您所发现的,现在的解决方法是删除无关的as_slice调用.但是,使用动态大小类型(DST),我们将能够写impl StrSlice for str,然后slice.as_slice() 将返回&'a str,因为不会再增加引用层(即self: &'a str).

As you discovered, the fix now is just removing the extraneous as_slice call. However, with dynamically sized types (DST), we will be able to write impl StrSlice for str, and then slice.as_slice() will be returning a &'a str, since there won't be an extra layer of references (that is, self: &'a str).

这篇关于为什么变量的寿命不足?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 04:36