我能否拥有一个静态借用的trait对象引用?

7
有没有一种方法可以让我获取一个结构体对某个 trait 的实现的静态借用引用?
trait Trait {}

struct Example;
impl Trait for Example {}

这个可以正常工作:

static instance1: Example = Example;

这也是可以正常工作的:
static instance2: &'static Example = &Example;

但是这样做不起作用:
static instance3: &'static Trait = &Example as &'static Trait;

它因此失败:

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`

另外,是否有一种方法可以从全局借用的静态结构指针中获取到一个被借用的静态 trait 指针:

static instance2: &'static Example = &Example;

fn f(i: &'static Trait) {
    /* ... */
}

fn main() {
    // how do I invoke f passing in instance2?
}

感谢您的回复,我只是在问题中匆忙编写了代码,所以感谢您处理错别字。我已经更新到 Rust Nightly 版本,这似乎解决了一些问题,但您知道如何将一个静态借用指针转换为常量表达式中的 trait 吗?这似乎是我遇到的最大问题。 - LorenVS
抱歉,我不知道。使用 as &'static T 似乎很直观,但编译器会拒绝它。可能目前还不可能实现。如果是这样,您可以通过在使用静态变量时进行强制转换来解决问题。或者,如果可能的话,使用类型参数而不是 trait 对象。在 Rust 中很少使用 trait 对象,大多数情况下类型参数会更好。 (当我开始使用 Rust 时,我经常在不必要的情况下使用 trait 对象)。例如,fn f<T: MyTrait>(i: &T) { /* ... */ } 是一个可以用任何实现了 MyTrait 的对象调用的函数。 - Zargony
1个回答

7

如果trait也实现了Sync,那么你可以这样做:

trait Trait: Sync {}

struct Example;
impl Trait for Example {}

static INSTANCE3: &dyn Trait = &Example;

或者如果你声明你的 trait 对象 实现了 Sync:

trait Trait {}

struct Example;
impl Trait for Example {}

static INSTANCE3: &(dyn Trait + Sync) = &Example;

实现Sync的类型是那些可以在线程之间安全地共享引用的类型。

[...] 当编译器确定适合时,将自动实现此trait。

精确的定义是:如果类型T&TSend,则该类型T就是Sync。换句话说,当在线程之间传递&T引用时,不存在未定义行为(包括数据竞争)的可能性。

由于您正在共享一个引用,因此任何线程都能够调用该引用上的方法,因此您需要确保如果发生这种情况,没有违反Rust的规则。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接