Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
897 views
in Technique[技术] by (71.8m points)

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

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?
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...