非引用类型是否总是满足 'static 生命周期?

3

我正在尝试理解下面的代码为什么可以编译。我原本以为无法构造 Wrapper<String> ,因为 T: 'static 并且运行时分配的字符串无法在整个程序生命周期中存在。

我认为之所以允许这样做是因为我将 T 设置为非引用类型(String)。当我使用一个 &str 或一个包含引用的结构体时,编译器会发出我期望的错误。

然而,我在 Rust 文档中没有找到证实我的假设的任何内容,所以也许我并不完全理解规则。所有非引用类型都满足对 Wrapper<T>'static 生命周期限制吗?还是有些类型会失败?

use rand::Rng;

struct Wrapper<T>
where
    T: 'static,
{
    value: T,
}

fn wrap_string() -> Wrapper<String> {
    // Use rng to avoid construcing string at compile time
    let mut rng = rand::thread_rng();
    let n: u8 = rng.gen();
    let text = format!("The number is {}", n);
    Wrapper { value: text }
}

fn main() {
    let wrapped = wrap_string();
    std::mem::drop(wrapped);
}

看起来你的问题可能已经被 What does the 'static lifetime mean in a trait bound in a Rust future? 的(重复)答案回答了。如果不是,请 [编辑] 你的问题以解释差异。否则,我们可以将此问题标记为已回答。 - Shepmaster
1
我认为这个问题更具体地询问了一个没有静态生命周期的类型为什么仍然满足绑定T:'static。这似乎与链接问题中提出的更一般的问题以及它标记为重复的问题不同。(顺便说一下,通过阅读那些答案,我无法找到这个问题的答案。) - Alistair
2个回答

5

来自RFC 2093的背景部分

[...] 为了使引用类型 &'a T "良好形式"(有效),编译器必须知道类型 T "outlives" 生命周期 'a - 意味着类型 T 中包含的所有引用都必须在生命周期 'a 内有效。因此,例如,类型 i32 超越任何生命周期,包括 'static,因为它根本没有引用。

所以我想说,对于你的问题,答案是:是的,任何没有引用(或仅包含静态引用)的类型都满足 'static 约束。

附注:根据该RFC,类似 T: 'staticT: 'a 的约束被称为 outlives requirements


3
您可以将类型约束T: 'x视为“T的实例不会因为某些比'x生命周期更短的东西被丢弃而突然无效”。但这并不影响T实例本身的生命周期。
因此,如果所引用的内容被丢弃,则引用将变为无效。这意味着所引用的内容至少必须与'x一样长-在'static的情况下是整个程序的运行时间。
但拥有其所有数据的东西-例如i32String-永远不会因为其他东西被丢弃而变得无效。一个整数在自身被丢弃之前一直是好的。因此它满足'static约束。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接