Я хочу создать структуру, которая будет служить оболочкой для глобального 'static
константа синглтона. Для этого я создал структуру Wrapper
, содержащую указатель на T
.
fn main() {
let s = Box::new(TestStruct {}) as Box<dyn TestTrait>;
let l = Wrapper::new(s);
tokio::spawn(async move { l.run().await });
}
struct Wrapper<T: Send + Sync + 'static> {
ptr: *const T,
// _phantom: std::marker::PhantomData<T>, // Use instead of ptr for tests
}
impl<T: Send + Sync + 'static> Wrapper<T> {
pub fn new(item: T) -> Self {
todo!();
}
}
impl<T: Send + Sync + 'static> std::ops::Deref for Wrapper<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
todo!();
}
}
unsafe impl<T: Send + Sync + 'static> Sync for Wrapper<T> {}
unsafe impl<T: Send + Sync + 'static> Send for Wrapper<T> {}
trait TestTrait: Send + Sync {
fn run(&self) -> futures::future::BoxFuture<()>;
}
struct TestStruct {}
impl TestTrait for TestStruct {
fn run(&self) -> futures::future::BoxFuture<()> {
todo!();
}
}
error[E0477]: the type `std::boxed::Box<dyn TestTrait>` does not fulfill the required lifetime
--> src/main.rs:4:5
|
4 | tokio::spawn(async move { l.run().await });
| ^^^^^^^^^^^^
|
= note: type must satisfy the static lifetime
Проблема странная, потому что, если я удаляю unsafe impls
и заменяю ptr
на _phantom
, программа компилируется. Похоже, добавление unsafe impl
с 'static
временем жизни прерывает некоторые внутренние проверки.
Подводя итог:
- нет указателя в структуре, нет
unsafe impl
s - нет ошибка - указатель в структуре, нет
unsafe impl
с - ошибка, потому что ptr
не Sync
+ Send
, это нормально - нет указателя в структуре,
unsafe impl
с - ошибка, не 'static
(???) - указатель в структуре,
unsafe impl
s - ошибка, не 'static
(???)
Имею прочитайте Как мне создать глобальный изменяемый синглтон? и Как создать безопасный статический синглтон c в Rust? . Меня не интересует, как создать глобальный синглтон, мне любопытно, почему мой пример не компилируется, будь то ошибка компилятора или где именно я ошибаюсь в своем коде.