为什么在第一种情况下明确注释了所需的寿命,而在第二种情况下不明确注释?

发布于 2025-02-02 22:33:57 字数 862 浏览 3 评论 0原文

在这里,需要注释'a项目是必需的:

struct App<'a> {
    items: StatefulList<'a, (&'a str, &'a str, usize)>,
}

impl<'a> App<'a> {
    fn new(items: &'a Vec<(&'a str, &'a str, usize)>) -> App<'a> {
        App {
            items: StatefulList::with_items(items),
        }
    }
}

但是,这不是:

struct StatefulList<'a, T> {
    state: ListState,
    items: &'a Vec<T>,
}

impl<'a, T> StatefulList<'a, T> {
    fn with_items(items: &Vec<T>) -> StatefulList<T> {
        StatefulList {
            state: ListState::default(),
            items,
        }
    }
}

为什么?

目前,我认为这是因为编译器在第一种情况下无法弄清楚寿命。

Here, the annotating 'a explicitly for items is required:

struct App<'a> {
    items: StatefulList<'a, (&'a str, &'a str, usize)>,
}

impl<'a> App<'a> {
    fn new(items: &'a Vec<(&'a str, &'a str, usize)>) -> App<'a> {
        App {
            items: StatefulList::with_items(items),
        }
    }
}

However, here it is not:

struct StatefulList<'a, T> {
    state: ListState,
    items: &'a Vec<T>,
}

impl<'a, T> StatefulList<'a, T> {
    fn with_items(items: &Vec<T>) -> StatefulList<T> {
        StatefulList {
            state: ListState::default(),
            items,
        }
    }
}

Why is that?

For now, I think it is because the compiler can't figure out the lifetime in the first case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自控 2025-02-09 22:33:57

由于这个小小的事情:

fn with_items(items: &Vec<T>) -> StatefulList<T> {
//                                           ^ here, where did the lifetime go?

statefullist在一生中声明。但是您省略了一生!省略它的生命是什么?

它是寿命的幼稚,'_或“算出”寿命。编译器通过简单 liftime Elision Elision Elision ulision规则。这些规则的一部分是,当参数中只有一个寿命(如在这种情况下 - 项目的隐式寿命:&amp; vec&lt; t&gt;),返回类型中的寿命所有人都没有。因此,明确书写的签名是:

fn with_items<'b>(items: &'b Vec<T>) -> StatefulList<'b, T>

'aimpl block 完全不使用 。返回的statefullist具有与参数相同的寿命 - 非常好,因为您将参数用于items

在第一种情况下,另一方面,我们从Impl block中明确指定'a寿命。您仍然使用该参数,因此参数的寿命必须匹配 - 并且必须为'a

有一块棉布可以帮助您避免这种情况:称为 elided_lifetimes_in_paths ,是rust_2018_idioms lints group的一部分,我强烈推荐#! ]新项目。如果您愿意,编译器将抱怨:

error: hidden lifetime parameters in types are deprecated
  --> src/lib.rs:12:51
   |
12 |     fn with_items(items: &Vec<T>) -> StatefulList<T> {
   |                                                   ^ expected named lifetime parameter
   |
note: the lint level is defined here
  --> src/lib.rs:1:11
   |
1  | #![forbid(rust_2018_idioms)]
   |           ^^^^^^^^^^^^^^^^
   = note: `#[forbid(elided_lifetimes_in_paths)]` implied by `#[forbid(rust_2018_idioms)]`
help: consider using the `'_` lifetime
   |
12 |     fn with_items(items: &Vec<T>) -> StatefulList<'_, T> {
   |                                                   +++

Because of this litte thing:

fn with_items(items: &Vec<T>) -> StatefulList<T> {
//                                           ^ here, where did the lifetime go?

StatefulList is declared with a lifetime. But you omitted the lifetime! What is the lifetime when you omit it?

It is the elided lifetime, '_, or the "figure it out" lifetime. And the compiler "figures it out" via simple liftime elision rules. And part of these rules is that when there is only one lifetime in the parameters (like in this case - the implicit lifetime of the items: &Vec<T>), the lifetimes in the return type all inhreit it. So written explicitly, the signature is:

fn with_items<'b>(items: &'b Vec<T>) -> StatefulList<'b, T>

The 'a lifetime from the impl block is not used at all. The returned StatefulList has the same lifetime as the parameter - which is excellent, because you use the parameter for its items!

In the first case, on the other hand, we explicitly specify the 'a lifetime from the impl block. You still use the parameter, and so the parameter's lifetime has to match - and it has to be 'a too.

There is a lint that will help you avoid that situation: it is called elided_lifetimes_in_paths, and is part of the rust_2018_idioms lints group which I strongly recommend #![forbid]ing for new projects. If you will do that, the compiler will complain:

error: hidden lifetime parameters in types are deprecated
  --> src/lib.rs:12:51
   |
12 |     fn with_items(items: &Vec<T>) -> StatefulList<T> {
   |                                                   ^ expected named lifetime parameter
   |
note: the lint level is defined here
  --> src/lib.rs:1:11
   |
1  | #![forbid(rust_2018_idioms)]
   |           ^^^^^^^^^^^^^^^^
   = note: `#[forbid(elided_lifetimes_in_paths)]` implied by `#[forbid(rust_2018_idioms)]`
help: consider using the `'_` lifetime
   |
12 |     fn with_items(items: &Vec<T>) -> StatefulList<'_, T> {
   |                                                   +++
酒与心事 2025-02-09 22:33:57

问题是,在第二个中,您不返回任何必须处理终身的内容,而是statefullist的所有版本。在第一个中,它需要将生命周期与您要返回的内容相匹配,以确保您返回的数据可能足够寿命。

实际上,您甚至不需要一些注释,因为编译器会为您限制一生。

impl<'a> App<'a> {
    fn new(items: &'a Vec<(&str, &str, usize)>) -> App<'a> {
        App {
            items: StatefulList::with_items(items),
        }
    }
}

&amp; str至少需要至少&amp;'vec

The thing is that in the second one you do not return anything that has to deal with lifetimes, but an owned version of StatefulList. In the first one it need to match the lifetime to what you are returning, to ensure that the data you return may live enough.

In fact you don't even need some of the annotations, since the compiler will coerce the lifetime for you.

impl<'a> App<'a> {
    fn new(items: &'a Vec<(&str, &str, usize)>) -> App<'a> {
        App {
            items: StatefulList::with_items(items),
        }
    }
}

&str need to live at least as much as &'a Vec.

Playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文