rust 是否可以将Arc〈dyn T>转换为Arc〈Mutex〈dyn T>>?

mwkjh3gx  于 2022-12-26  发布在  其他
关注(0)|答案(1)|浏览(221)

在rust中,我可以将Arc<i32>转换为Arc<Mutex<i32>>

let num = 5;
let arc_num = Arc::new(num);
let mtx_num = Arc::new(Mutex::new(*(arc_num.deref())));

但在特质方面,这种转换就失败了:

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

pub trait T {}

#[derive(Copy, Clone)]
pub struct Var {

}
impl T for Var {}

pub fn convert(var: Arc<dyn T>) -> Arc<Mutex<dyn T>> {
    return Arc::new(Mutex::new(*(var.deref())));
}

因为*(var.deref())在编译时不知道大小。
那么,是否有可能将Arc<dyn T>转换为Arc<Mutex<dyn T>>呢?

ewm0tg9j

ewm0tg9j1#

只有在这种特质的帮助下,

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

pub trait T {
    fn mutexme(self: Arc<Self>) -> Arc<Mutex<dyn T>>;
}
#[derive(Copy, Clone)]
pub struct Var {}
impl T for Var {
    fn mutexme(self: Arc<Self>) -> Arc<Mutex<dyn T>> {
        Arc::new(Mutex::new(*self))
    }
}

pub fn convert(var: Arc<dyn T>) -> Arc<Mutex<dyn T>> {
    var.mutexme()
}

问题是编译器不知道dyn T的大小,所以它不能在堆栈上保留足够的空间,也不能将数据复制到那里。
即使您以某种方式克服了这个问题,您的dyn T也可能不是Copy,甚至不是Clone,因为trait T不需要这样做,如果它这样做了,它就不是对象安全的,因为Clone不是。
您也不需要导入Deref,因为您可以像我上面所做的那样将其与它的操作符*一起使用。

相关问题