本文介绍了为什么要在结构中使用相同的生命周期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题类似于何时是在结构中定义多个生命周期有用吗?,但希望足够不同.该问题的答案很有帮助,但侧重于一种方法的优点(对结构中的引用使用不同的生命周期),而不是缺点(如果有的话).像这样,这个问题正在寻找有关在创建结构时如何选择生命周期的指导.

This question is similar to When is it useful to define multiple lifetimes in a struct?, but hopefully different enough. The answer to that question is helpful but focuses on advantages of one approach (using distinct lifetimes for references in struct) but not on drawbacks (if any). This question, like that, is looking for guidance on how to choose lifetimes when creating structs.

将其称为 捆绑在一起 版本,因为 xy 需要具有相同的生命周期:

Call this the tied together version because x and y are required to have the same lifetime:

struct Foo<'a> {
    x: &'a i32,
    y: &'a i32,
}

并将其称为宽松版本,因为生命周期可能会有所不同:

and call this the loose version because lifetimes can vary:

struct Foo<'a, 'b> {
    x: &'a i32,
    y: &'b i32,
}

所引用问题的答案给出了一个明确的案例,即客户端代码可以在给定 松散 版本的情况下编译/运行,但对于 捆绑在一起 版本将失败.是不是任何适用于捆绑在一起版本的客户端代码也适用于松散版本并保证同样安全em>(即安全)?反面是不正确的.从结构设计者的角度来看,宽松 版本显然更灵活.鉴于这是一个好的/可接受的答案,指导可能是 - 在结构中使用引用时总是给它们不同的生命周期.

The answer to the referenced question gives a clear case where client code can compile/run given the loose version but will fail for the tied together version. Isn't it the case that any client code that works for the tied together version will also work for the loose version and will be guaranteed just as safe (i.e. safe)? The obverse is not true. The loose version is clearly more flexible from a struct designer perspective. Given it is a good/accepted answer the guidance might be - when using references in a struct always give them distinct lifetimes.

这个建议的缺点是什么,忽略了额外的输入?例如,要求结构中的引用具有相同的生命周期是否有好处?

What is the drawback to this advice, ignoring the extra typing? For example, is there ever benefit to requiring references in a struct have the same lifetime?

推荐答案

是的,它不仅仅是一个结构体.如果生命周期总是彼此不同,那么你就不能写这个函数:

Yes, and it goes beyond having a struct. If lifetimes were always distinct from each other, then you couldn't write this function:

fn foo<'a, 'b>(a: &'a str, b: &'b str) -> &str {
    // What lifetime to return?
    if (global_random_number() == 42) {
        a
    } else {
        b
    }
}

应用到结构体,你可以有这样的东西:

Applying to the struct, you could have something like this:

struct EvenOrOdd<'a, 'b> {
    even: &'a str,
    odd: &'b str,
}

impl<'a, 'b> EvenOrOdd<'a, 'b> {
    fn do_it(&self, i: u8) -> &str {
        if i % 2 == 0 {
            self.even
        } else {
            self.odd
        }
    }
}

请注意,在编译时,它不会返回比结构本身寿命更长的字符串,这不是预期的.此代码失败,即使它应该能够工作:

Note that while this compiles, it doesn't return a string that can outlive the structure itself, which is not what was intended. This code fails, even though it should be able to work:

fn foo<'a, 'b>(a: &'a str, b: &'b str) {
    let result = { EvenOrOdd { even: a, odd: b }.do_it(42) };

    println!("{}", result);
}

这将适用于统一的生命周期:

This will work with unified lifetimes:

struct EvenOrOdd<'a> {
    even: &'a str,
    odd: &'a str,
}

impl<'a> EvenOrOdd<'a> {
    fn do_it(&self, i: u8) -> &'a str {
        if i % 2 == 0 {
            self.even
        } else {
            self.odd
        }
    }
}

这与链接的答案相反,后者有评论:

This is the opposite of the linked answer, which has the comment:

您希望能够在使用后获取聚合值并拆分其中的一部分

在这种情况下,我们想要获取一个聚合值并将它们统一.

In this case, we want to take an aggregate value and unify them.

在极少数情况下,您可能需要在不同和统一的生命周期之间穿梭:

In rarer occasions, you may need to thread the needle between distinct and unified lifetimes :

struct EvenOrOdd<'a, 'b: 'a> {
    even: &'a str,
    odd: &'b str,
}

impl<'a, 'b> EvenOrOdd<'a, 'b> {
    fn do_it(&self, i: u8) -> &'a str {
        if i % 2 == 0 {
            self.even
        } else {
            self.odd
        }
    }
}

虽然这在需要时很有用,但我无法想象如果我们每次都必须这样写,会爆发出的哀号和咬牙切齿.

While this is useful when needed, I can't imagine the wailing and gnashing of teeth that would erupt if we had to write it this way every time.

忽略额外的输入

我不会.有

foo<'a>(Bar<'a>)

绝对比

foo<'a, 'b', 'c, 'd>(Bar<'a, 'b', 'c, 'd>)

当您没有从额外的通用参数中受益时.

When you aren't benefiting from the extra generic parameters.

这篇关于为什么要在结构中使用相同的生命周期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 11:24