Как мне привести Arc<RwLock<dyn Child>> к Arc<RwLock<dyn Base>>

В настоящее время у меня есть такой код:

use std::sync::{Arc, RwLock};

// Define traits
trait Child: Base {
    fn method_a(&self);
}

trait Base {
    fn method_b(&self);
}

// Struct implementing both traits
struct MyStruct {
    something: i32,
};

impl Child for MyStruct {
    fn method_a(&self) {
        println!("Method A");
    }
}

impl Base for MyStruct {
    fn method_b(&self) {
        println!("Method B");
    }
}

fn do_some_processing(parent: &Arc<RwLock<dyn Child>>) -> Arc<RwLock<dyn Base>> {
    //How do i do this?
}

fn main() {
    let my_struct = Arc::new(RwLock::new(MyStruct));

    let base = do_some_processing(&my_struct);

}

Я хочу ограничить функции, используемые после вызова do_some_processing. В этом причина двух черт.

Кстати, любой вызывающий do_some_processing по-прежнему сможет получить доступ к оригиналу как dyn Child, поскольку здесь ничто не мешает им хранить оригинал Arc.

kmdreko 01.09.2024 03:53

@kmdreko, это интересный момент, спасибо, что сообщили мне.

ZNackasha 01.09.2024 06:47
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
0
2
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Апкастинговое принуждение пока не стабильно. Так что это может сработать +nightly

#![feature(trait_upcasting)]
use std::sync::{Arc, RwLock};

// Define traits
trait Child: Base {
    fn method_a(&self);
}

trait Base {
    fn method_b(&self);
}

// Struct implementing both traits
struct MyStruct {
    something: i32,
}

impl Child for MyStruct {
    fn method_a(&self) {
        println!("Method A");
    }
}

impl Base for MyStruct {
    fn method_b(&self) {
        println!("Method B");
    }
}

fn do_some_processing(parent: &Arc<RwLock<dyn Child>>) -> Arc<RwLock<dyn Base>> {
    parent.clone()
}



fn main() {
    let my_struct: Arc<RwLock<dyn Child>> = Arc::new(RwLock::new(MyStruct { something: 42 }));

    let base = do_some_processing(&my_struct);

}

---ИЛИ---

Если вы хотите придерживаться стабильной версии, вам понадобится обертка.

use std::sync::{Arc, RwLock};

// Define traits
trait Child: Base {
    fn method_a(&self);
}

trait Base {
    fn method_b(&self);
}

// Struct implementing both traits
struct MyStruct {
    something: i32,
}

impl Child for MyStruct {
    fn method_a(&self) {
        println!("Method A");
    }
}

impl Base for MyStruct {
    fn method_b(&self) {
        println!("Method B");
    }
}

// Wrapper struct to manually upcast Child to Base
struct BaseWrapper {
    inner: Arc<RwLock<dyn Child>>,
}

impl Base for BaseWrapper {
    fn method_b(&self) {
        self.inner.read().unwrap().method_b();
    }
}

fn upcast(child: Arc<RwLock<dyn Child>>) -> Arc<RwLock<dyn Base>> {
    Arc::new(RwLock::new(BaseWrapper { inner: child }))
}

fn main() {
    let my_struct: Arc<RwLock<dyn Child>> = Arc::new(RwLock::new(MyStruct { something: 42 }));

    let base = upcast(my_struct);

    base.read().unwrap().method_b();
}

Другие вопросы по теме