Is there a way for me to obtain a static borrowed reference to a struct's implementation of a trait:
trait Trait {}
struct Example;
impl Trait for Example {}
This works fine:
static instance1: Example = Example;
This also works fine:
static instance2: &'static Example = &Example;
But this doesn't work:
static instance3: &'static Trait = &Example as &'static Trait;
It fails thus:
error[E0277]: the trait bound `Trait + 'static: std::marker::Sync` is not satisfied in `&'static Trait + 'static`
--> src/main.rs:10:1
|
10 | static instance3: &'static Trait = &Example as &'static Trait;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Trait + 'static` cannot be shared between threads safely
|
= help: within `&'static Trait + 'static`, the trait `std::marker::Sync` is not implemented for `Trait + 'static`
= note: required because it appears within the type `&'static Trait + 'static`
= note: shared static variables must have a type that implements `Sync`
Alternatively, is there a way to obtain a borrowed static pointer to a trait from a global borrowed static pointer to a struct:
static instance2: &'static Example = &Example;
fn f(i: &'static Trait) {
/* ... */
}
fn main() {
// how do I invoke f passing in instance2?
}
We create a trait object by specifying some sort of pointer, such as a & reference or a Box<T> smart pointer, then the dyn keyword, and then specifying the relevant trait.
Rust provides dynamic dispatch through a feature called 'trait objects'. Trait objects, like &Foo or Box<Foo> , are normal values that store a value of any type that implements the given trait, where the precise type can only be known at runtime.
Yes, you can, if the trait also implements Sync
:
trait Trait: Sync {}
struct Example;
impl Trait for Example {}
static INSTANCE3: &dyn Trait = &Example;
Or if you declare that your trait object also implements Sync
:
trait Trait {}
struct Example;
impl Trait for Example {}
static INSTANCE3: &(dyn Trait + Sync) = &Example;
Types that implement Sync
are those
[...] for which it is safe to share references between threads.
This trait is automatically implemented when the compiler determines it's appropriate.
The precise definition is: a type
T
isSync
if&T
isSend
. In other words, if there is no possibility of undefined behavior (including data races) when passing&T
references between threads.
Since you are sharing a reference, any thread would be able to call methods on that reference, so you need to ensure that nothing would violate Rust's rules if that happens.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With