我对静态特征界限的理解是否正确?

Is my understanding of static trait bounds correct?

我正在使用 specs ECS 库并且我有以下类型

trait TradeableResource{}

#[derive(Component)]
struct MarketMaker<T: TradeableResource + std::marker::Send + std::marker::Sync + 'static>{
    lot_size:T
}

如果没有 'static 约束,则无法编译。我最初担心这将意味着这个结构的所有值都必须在程序的整个生命周期中存在,but looking ,看来这种担忧是无效的。这些链接清楚地处理了主题,但我觉得他们没有使用为我产生清晰思维模型的语言。所以我想就这个话题发表自己的看法,你告诉我我是否正确。

我的发言

通过使用 'static 约束,任何填充 T 位置的类型都必须

  1. 完全由自有值组成,或者
  2. 如果它包含引用值,则这些值必须与程序的生命周期一样长。

所以下面的具体情况不需要任何东西来完成程序的整个生命周期

#[derive(Component)]
struct Food(f64);
impl TradeableResource for Food{}

fn main() {
    let mut world = World::new();
    world.register::<MarketMaker<Food>>();

    world.create_entity().with(MarketMaker { lot_size: Food(4.0)}).build();
}

因为类型 Food 只包含拥有的值,没有引用。

我没听错吗?

TLDR:是的,你没看错。

确实 'static 这个词有点过载了。它可以用作生命周期说明符,例如:

const T: &'static str = "static string here";

fn handle_static<T>(t: &'static T) { .. }

并作为绑定类型:

trait T: 'static { .. }

fn handle_owned<T>(t: T)
where T: 'static { .. }

这些是完全不同的情况,您的示例与第二个示例类似。您的陈述是正确的,以下示例说明了这一点 (playground):

struct X<'a> {
    borrowed_str: &'a str,
}

let base_str = "".to_string();
// X'es lifetime bounded by base_str
let borrows = X {
    borrowed_str: base_str.as_str(),
};
let borrows_static = X { borrowed_str: "" };

fn f<T>(t: T) where T: 'static {}

// the following line fails to compile
// f(borrowed);

f(borrows_static); // though, with 'static lifetime works
f(base_str); // owned, also works fine

我还建议你看看 amazing Common Rust Lifetime Misconceptions post 如果你想要一个关于那个或类似误解的结构化指南。