Can I have a static borrowed reference to a trait object?

馋奶兔 提交于 2019-11-26 23:36:09

问题


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?
}

回答1:


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 is Sync if &T is Send. 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.



来源:https://stackoverflow.com/questions/19667717/can-i-have-a-static-borrowed-reference-to-a-trait-object

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!