我对静态特质界限的理解正确吗?

时间:2020-06-11 11:20:41

标签: rust traits

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

trait TradeableResource{}

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

如果没有'static约束,则无法编译。最初,我担心这意味着该结构的所有值都必须在程序but looking around的整个生命周期中都有效,看来这种担心是无效的。这些链接显然涉及该主题,但是我觉得他们没有使用对我有清晰思维模式的语言。因此,我想就这个话题发表自己的看法,然后您告诉我我是否正确。

我的声明

通过使用'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仅包含拥有的值,而没有引用。

我说对了吗?

1 个答案:

答案 0 :(得分:4)

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

如果您想要有关该错误或类似误解的结构化指南,我还建议您阅读令人惊叹的Common Rust Lifetime Misconceptions帖子。