繁体   English   中英

Arc 包装的同一实例的多个特征对象<mutex<_> > </mutex<_>

[英]Multible trait objects of the same instance wrapped by Arc<Mutex<_>>

目标是让 object ( callback_handler ) 实现特征ABC ,这些特征可以传递给不同的函数,例如期望类型为AB的特征 object 。

这需要callback_handler和 trait 对象由同一个Mutex保护(因为,例如,trait A期望&mut self )。 此外,要使此设置生效,必须将此Mutex包装在ArcRc中:

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

trait A {
    fn a(&mut self) {}
}
trait B {}
trait C: A + B {}

struct Foo {}

impl A for Foo {}
impl B for Foo {}
impl C for Foo {}

fn register_for_A(callback_handler: Arc<Mutex<Box<dyn A>>>) {
    // Register for callbacks defined in `A`.
    // Store the passed handler somewhere.
}

fn register_for_B(callback_handler: Arc<Mutex<Box<dyn B>>>) {
    // Register for callbacks defined in `B`.
    // Store the passed handler somewhere.
}

fn main() {
    let callback_handler = Arc::new(Mutex::new(Box::new(Foo{})));
    // Register for callbacks using different trait objects of the same "origin" object.
    // For this to be safe, all objects must be protected by the same ("shared") mutex.
    // !!! This will not work since there must be some steps to cast this to the right type. !!!
    register_for_A(Arc::clone(&callback_handler));
    register_for_B(Arc::clone(&callback_handler));

    // We can still use `callback_handler` to call methods on Foo ourself
}

现在,问题是,如何将Arc<Mutex<Box<Foo>>>类型的原点 object callback_hanlder转换/转换为Arc<Mutex<Box<dyn A>>>Arc<Mutex<Box<dyn B>>> 虽然我没有看到为什么这不可能的技术原因,但我不知道如何执行这样的转换以及它是否可行。 虽然一种解决方案是使用Any特性,但我希望有一种解决方案可以保留函数register_for_Aregister_for_B的编译时类型安全性。

你被智能指针Box + Arc的双重使用绊倒了你可以简单地将Arc<Mutex<Foo>>转换为Arc<Mutex<dyn A>>使用as ,真的没有必要另外将它Box :

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

trait A {
    fn a(&mut self) {}
}
trait B {}

struct Foo {}

impl A for Foo {}
impl B for Foo {}

fn register_for_A(callback_handler: Arc<Mutex<dyn A>>) {
    // Register for callbacks defined in `A`.
    // Store the passed handler somewhere.
}

fn register_for_B(callback_handler: Arc<Mutex<dyn B>>) {
    // Register for callbacks defined in `B`.
    // Store the passed handler somewhere.
}

fn main() {
    let callback_handler = Arc::new(Mutex::new(Foo{}));
    // Register for callbacks using different trait objects of the same "origin" object.
    // For this to be safe, all objects must be protected by the same ("shared") mutex.
    // !!! This will not work since there must be some steps to cast this to the right type. !!!
    register_for_A(Arc::clone(&callback_handler) as _);
    register_for_B(Arc::clone(&callback_handler) as _);

    // We can still use `callback_handler` to call methods on Foo ourself
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM