指定生命周期允许我返回一个引用。

huangapple go评论66阅读模式
英文:

Why does specifying a lifetime let me return a reference?

问题

I'm struggling to understand lifetimes. I understand (I think) that specifying a lifetime with input parameters (i.e. foo<'a>(x: &'a String) -> &'a String {}) means that the returned value inherits the lifetime of the input parameter and will therefore live as long as that does. However, the code below compiles just fine without any input parameters, so I don't understand how the compiler knows I wanted the reference to Dragon::Green to live long enough to leave scope. Is the ownership getting moved to a higher scope, or is something else happening?

fn main() {
  let d;

  {
    let dtile = testtile();
    d = dtile;
  }
  
  println!("{:?}", d);
}

#[derive(PartialOrd, Ord, PartialEq, Eq, Debug)]
enum Dragon {
    White,
    Green,
    Red
}

fn testtile<'a>() -> &'a Dragon {
    &Dragon::Green
}
英文:

I'm struggling to understand lifetimes. I understand (I think) that specifying a lifetime with input parameters (i.e. foo<'a>(x: &'a String) -> &'a String {}) means that the returned value inherits the lifetime of the input parameter and will therefore live as long as that does. However, the code below compiles just fine without any input parameters, so I don't understand how the compiler knows I wanted the reference to Dragon::Green to live long enough to leave scope. Is the ownership getting moved to a higher scope, or is something else happening?

fn main() {
  let d;

  {
    let dtile = testtile();
    d = dtile;
  }
  
  println!(&quot;{:?}&quot;, d);
}

#[derive(PartialOrd, Ord, PartialEq, Eq, Debug)]
enum Dragon {
    White,
    Green,
    Red
}

fn testtile&lt;&#39;a&gt;() -&gt; &amp;&#39;a Dragon {
    &amp;Dragon::Green
}

答案1

得分: 3

specifying a lifetime with input parameters (i.e. foo<'a>(x: &'a String) -> &'a String {}) means that the returned value inherits the lifetime of the input parameter

不完全正确。生命周期标识符是 描述性 的,而不是 规定性 的。

它们帮助 借用检查器 强制执行有关生命周期的规则。

每个引用都有一个生命周期。但有时你需要通过名称引用那个生命周期,这就是生命周期标识符的作用所在。

在你的例子中,发生的情况是,借用检查器看到 testtile 返回的引用必须与变量 d 一样长寿。然后它尝试找到一个 具体的 生命周期来替代泛型生命周期参数 &#39;a,使其可以正常工作。

在这种情况下,的确可以正常工作。例如,如果我们指定引用具有 &#39;static 生命周期,就没有问题。而且考虑到一个简单的枚举变量实际上只是一个常数,这里就没有问题。

在更复杂的情况下,可能找不到可以替代生命周期参数的有效生命周期,尽管这在更常见的情况下可能是因为,例如,Dragon 结构体本身 包含 引用。

英文:

> specifying a lifetime with input parameters (i.e. foo<'a>(x: &'a String) -> &'a String {}) means that the returned value inherits the lifetime of the input parameter

Not quite. Lifetime specifiers are descriptive, not prescriptive.

They help the borrow checker enforce rules around lifetimes.

Every reference has a lifetime. But sometimes you need to refer to that lifetime by name, and that's where lifetime specifiers come in.

In your example, what's happening is that the borrow checker sees that the reference returned by testtile must live as long as variable d. It then tries to find a concrete lifetime to substitute for the generic lifetime parameter &#39;a that would make that work.

In this case, that does indeed work. For example, if we specify that the reference has &#39;static lifetime, there's no problem. And given that a simple enum variant is really just a constant, there's no issue here.

In more complex cases, it might be that there's no valid way to find a lifetime to substitute for the lifetime parameter, though this would be more common if, for example, the Dragon struct itself contained references.

huangapple
  • 本文由 发表于 2023年2月27日 02:56:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75574319.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定