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


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方法文档,您会发现它不是为所有Result定义的,而是为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`

要解决这个问题,你还需要使盒装trait对象Send + Sync,以便它可以跨线程共享。

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

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

相关内容

  • 没有找到相关文章