rust - Trait Bound 不满足 Result<(), Box<(dyn SomeTrait + 'static)>>

标签 rust traits abstraction dynamic-dispatch

use once_cell::sync::OnceCell;

pub trait SomeTrait {}
pub struct Impl1 {}

impl SomeTrait for Impl1 {}

pub static GLOBAL_THING: OnceCell<Box<dyn SomeTrait>> = OnceCell::new();

pub fn main() {
    GLOBAL_THING.set(Box::new(Impl1 {})).unwrap();
}

我收到此错误,但不确定如何解释它的含义或修复它。

error[E0599]: the method `unwrap` exists for enum `Result<(), Box<(dyn SomeTrait + 'static)>>`, but its trait bounds were not satisfied
   --> src/main.rs:11:42
    |
11  |       GLOBAL_THING.set(Box::new(Impl1 {})).unwrap();
    |                                            ^^^^^^ method cannot be called on `Result<(), Box<(dyn SomeTrait + 'static)>>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
            `Box<dyn SomeTrait>: Debug`

一个简单的解决方法是只执行 if let Err() = GLOBAL_THING.set() {panic!(...)} 而不是使用 unwrap() ,但我想了解这里发生了什么,并在可能的情况下进行修复。

最佳答案

如果你看一下 unwrap method文档你会看到它没有为所有 Result 定义s,但只有那些 E: Debug :

impl<T, E> Result<T, E>
where
    E: Debug, 
{
    pub fn unwrap(self) -> T;
}

它需要错误类型 E实现Debug以便在解包失败时打印错误。

报错提示结果类型为Result<(), Box<(dyn SomeTrait + 'static)>> , 所以 E = Box<(dyn SomeTrait + 'static)> .您可以通过 SomeTrait: Debug 使此错误类型可调试,这要求任何实现 SomeTrait 的类型还必须实现 Debug .

pub trait SomeTrait: Debug {}

#[derive(Debug)]
pub struct Impl1 {}

一旦你这样做了,你会遇到下一个错误:

error[E0277]: `dyn SomeTrait` cannot be shared between threads safely
  --> src/main.rs:11:1
   |
11 | pub static GLOBAL_THING: OnceCell<Box<dyn SomeTrait>> = OnceCell::new();
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn SomeTrait` cannot be shared between threads safely
   |
   = help: the trait `Sync` is not implemented for `dyn SomeTrait`
   = note: required because of the requirements on the impl of `Sync` for `Unique<dyn SomeTrait>`
   = note: required because it appears within the type `Box<dyn SomeTrait>`
   = note: required because of the requirements on the impl of `Sync` for `once_cell::imp::OnceCell<Box<dyn SomeTrait>>`
   = note: required because it appears within the type `once_cell::sync::OnceCell<Box<dyn SomeTrait>>`
   = note: shared static variables must have a type that implements `Sync`

要解决此问题,您还需要制作盒装特征对象 Send + Sync以便它可以跨线程共享。

pub static GLOBAL_THING: OnceCell<Box<dyn SomeTrait + Send + Sync>> = OnceCell::new();

您可以在 Playground 上看到最终结果.

关于rust - Trait Bound 不满足 Result<(), Box<(dyn SomeTrait + 'static)>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69592445/

相关文章:

rust - 如果 HashMap 为空,从中删除值的惯用方法是什么?

rust - 自动派生 Arc 的特征实现

generics - 从泛型类型的特征调用静态方法

c++ - 与抽象函数的一致性

python - SQLAlchemy 条件过滤中的抽象

rust - UDP打洞: cannot send from server to client

rust - 嵌套匹配在惯用的 Rust 中是一种不好的做法吗?

rust - 在通用结构中派生 Show

php - 在 PHP 中自动加载特征

scala - "abstract over"是什么意思?