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

Che*_*vas 4 traits rust

我正在使用规范 ECS 库,并且我有以下类型

trait TradeableResource{}

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

如果没有约束,则无法编译'static。我最初担心这意味着这个结构体的所有值都必须在程序的整个生命周期中存在, 环顾 四周,这种担心似乎是无效的。这些链接清楚地涉及该主题,但我觉得它们没有使用为我提供清晰的心理模型的语言。所以我想就这个话题发表我自己的声明,你告诉我我是否正确。

我的声明

通过使用'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();
}
Run Code Online (Sandbox Code Playgroud)

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

我说得对吗?

Kit*_*tsu 5

TLDR:是的,您理解正确。

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

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

fn handle_static<T>(t: &'static T) { .. }
Run Code Online (Sandbox Code Playgroud)

并作为类型绑定:

trait T: 'static { .. }

fn handle_owned<T>(t: T)
where T: 'static { .. }
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

如果您想要有关该错误或类似错误概念的结构化指南,我还建议您查看令人惊叹的常见 Rust 终身错误概念帖子。