The full syntax for talking about a trait object is dyn TheTrait + 'a for some lifetime 'a. This means:
This value could contain a value of any type that implements TheTrait and for which it is legal to keep the trait object alive until the end of 'a.
When no lifetime is specified, there are some rules for what the default choice is. When its on its own, the default choice is 'static. When its behind a reference, the default lifetime is the lifetime on the reference.
But I wonder what is a static dynamic trait object? Maybe, I have some misunderstanding about static lifetime that dynamic trait objects will never have a static lifetime...
To my example above, how can I create a static lifetime dynamic trait, and passing it to a dyn trait + 'static?
If a trait object is annotated with 'static, that means the value inside it is such that it would be safe to keep the value alive forever (but not that you have to keep it around forever). Mainly this means that the type cannot contain any non-static references, as it would be invalid to keep such a reference around after the reference is invalidated.
You can create it like you create any other trait object.
Can you give an example to illustrate the use of a dynamic trait object which has 'static lifetime?
I modify my code to:
static s1: S = S{};
fn main() {
show(&s1);
}
To me, s1 has 'static lifetime, and so as &s1. But compiler reports error.
I know 'static lifetime isn't equal to static variables. From my view, the static variable exists all the time during the process running and should have the 'static lifetime. Correct me if I am wrong on the state that static variable is a subset of variables that have 'static lifetime.
I will appreciate it if you can give me an example of this.
By the way, I wonder is that possible to use dyn Trait instead of &dyn Trait as the function's parameter type?
Change fcuntion signature from fn show(v: &dyn AsBool) to fn show(v: dyn AsBool) incurs error:
21 | fn show(v: dyn AsBool) {
| ^ doesn't have a size known at compile-time
No, you need a &dyn Trait or a Box<dyn Trait> or some other sort of indirection, just like you do with str and [T]. Every str might have a different size (length), even though they have the same type, and so too can every dyn Trait.
Does your declaration of is_false look something like this?
impl dyn AsBool {
pub fn is_false(&'static self) -> bool {
// ^^^^^^^ this part in particular
!self.as_bool()
}
}
If so, this is the distinction between a &'static reference (which points to something like a static variable, promoted constant, or leaked memory), or to a static bound. The &'static reference is much more restricted. Just because T: 'static doesn't mean you can create a &'static T from it. A &'static T is a reference to something that definitely lasts as long as the current thread, where as a T: 'static bound just means that the type could conceivably last that long -- but it doesn't have to.
If the compiler can't prove your data will last "forever", it won't let you safely take a &'static reference to it (or you could end up with a dangling reference). That's why the things &'static can safely reference are so restricted -- those are the things the compiler can prove last "forever".
Note also how the help is telling you to make it &'static (dyn AsBool + 'static) and not just &(dyn AsBool + 'static).
The takeaway is that you probably want & and not &'static, and that you should understand the distinction between &'static T and &T where T: 'static.