Reputation: 2312
I am using the specs ECS library and I have the following type
trait TradeableResource{}
#[derive(Component)]
struct MarketMaker<T: TradeableResource + std::marker::Send + std::marker::Sync + 'static>{
lot_size:T
}
This does not compile without the 'static
constraint. I was initially concerned that this would mean that all values of this struct will have to live for the entire life of the program, but looking around, it seems the concern is invalid. Those links clearly deal with the topic but I feel they don't use language that results in a clear mental model for me. So I'd like to make my own statement about the topic, and you tell me if I am correct.
My statement
By using the 'static
constraint, any type that fills the place of T
must either
So the following specific case would not require anything to live the entire life of the program
#[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();
}
Because the type Food
contains only owned values, no references.
Have I got that right?
Upvotes: 4
Views: 311
Reputation: 3445
TLDR: yes, you got it correctly.
Indeed 'static
term is a lit bit overloaded. It can be used as a lifetime specifier, e.g:
const T: &'static str = "static string here";
fn handle_static<T>(t: &'static T) { .. }
and as the type bound:
trait T: 'static { .. }
fn handle_owned<T>(t: T)
where T: 'static { .. }
These are fairly different cases and yours example is similar to the second one. Your statements are correct and the following example illustrates it (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
I also suggest you to look at amazing Common Rust Lifetime Misconceptions post if you want a structured guide to that or similar misconceptions.
Upvotes: 5