Rust 中结构的生命周期界限如何工作?

2024-03-24

昨天IRC里对此有一些讨论,让我感到隐隐约约的不满。

问题是:

如何在结构上定义生命周期以将其内容限制为 只有与“自身”一样长寿的事物。

i.e. a 'self那类的东西。

我最初的反应是:你不能。

如果你创建一个结构体Foo<'a>,与其关联的生命周期是从它包含的引用推断出来的;除非该结构包含对itself(不可能),你不能有这样的'self寿命。

关于这个问题有很多讨论,最后我写了因此:

#[derive(Debug)]
struct Bar;

#[derive(Debug)]
struct Foo<'a> {
  a:&'a Bar,
  b:&'a Bar
}

fn factory<'a>(v1:&'a Bar, v2: &'a Bar) -> Foo<'a> {
  return Foo {
    a: v1,
    b: v2
  };
}

fn main() { // <---- Let's call this block lifetime 'one
  let a = Bar; 
  let c = &a; // <-- C has lifetime 'one
  { // <------------ Let's call this block lifetime 'two
    let b = Bar;

    let mut foo1 = factory(c, c);  
    foo1.b = &b;

    let mut foo2 = factory(&b, &b);  
    foo2.a = &a;

    println!("{:?}", foo1);
    println!("{:?}", foo2);
  }
}

然而,我现在的困惑非但没有减少,反而更多了。

所以,严格意义上来说:

  • c has 'one
  • &b has 'two
  • 'static > 'one > 'two(那是,'two的边界是'one).
  • foo1 has 'one
  • foo2 has 'two

现在,我的困惑是:

Foo<'a>表明'a is the 最小寿命界限可以包含在以下实例中Foo.

  • Since 'one > 'two, foo2应该能够包含一个&'one a;这有效。

  • Since 'two > 'one, foo1 should not能够容纳&'two b;然而,这有效。

Why?

看来我的困惑是由两个误解之一造成的:任何一个:

  1. 的实例foo1事实上是Foo<'two>, not Foo<'one>.

    我不明白为什么会出现这种情况,因为它是在factory<'a> where <'a>是的生命周期c;这是'one, not 'two。绝对没有办法c can be &'two在上面的例子中。一生'two在函数工厂中不可用Foo被建造。

2)结构生命周期并不像我理解的那样工作;即一生'a on a Foo实例在创建实例之后可以以某种方式改变(例如在移动时?)

……但我不知道是哪一个。


参考的生命周期参数是协变:它们可以替换为shorter必要时终身。

基本上,你的做法是错误的。当你有一个&'one Bar,您不能将引用分配给带有shorter生命周期(例如'two此处),否则当执行离开时,引用将悬空'two范围。然而,当你有一个&'two Bar,您可以将引用分配给具有较长生命周期的值(例如'one and 'static),因为引用将在引用对象之前超出范围。

为什么你的程序可以编译?编译器不仅使用来自调用的信息factory选择适当的寿命;它还使用作业中的信息 https://doc.rust-lang.org/stable/rust-by-example/types/inference.html. &a有类型&'one Bar and &b有类型&'two Bar。因为'two之后开始'one并在之前结束'one,编译器可以coerce a &'one Bar to a &'two Bar。用面向对象的术语来说,&'one Bar is a &'two Bar (&'one Bar是一个子类型&'two Bar)。就像在 Java 中一样,你可以传递一个String作为期望的函数的参数Object。 Java 中类的子类型关系是子类是其父类的子类型,但生命周期的子类型关系是较长生命周期是较短生命周期的子类型。

这意味着我们找到了一个通用类型&a and &b: &'two Bar。因此,编译器推断'two for 'a在致电factory.

请注意,类型foo2分配时不会改变;值的类型始终是静态的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rust 中结构的生命周期界限如何工作? 的相关文章

随机推荐