如何在 Rust 中序列化 Arc<Mutex<T>>?

Ana*_*kov 4 rust serde

我有一个特质DataSet,我是Serialize这样实现的:

impl Serialize for dyn DataSet {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut seq = serializer.serialize_map(Some(2))?;
        seq.serialize_entry("fields", "Hello")?;
        seq.serialize_entry("measures", "There")?;
        seq.end()
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在程序/应用程序中,我共享指向特征对象的指针:

let x: Arc<Mutex<dyn DataSet>> = Arc::new(Mutex::new(data));
Run Code Online (Sandbox Code Playgroud)

哪里data有实现 DataSet 的对象。

现在,我想把这个对象转换成json(即序列化它):

serde_json::to_string(&x)
Run Code Online (Sandbox Code Playgroud)

它适用于Box而不是Arc<Mutex<>>. 但Arc<Mutex<>>编译器抱怨:

the size for values of type `dyn base_engine::DataSet` cannot be known at compilation time
the trait `Sized` is not implemented for `dyn base_engine::DataSet`
the trait `Serialize` is implemented for `Arc<T>`
required because of the requirements on the impl of `Serialize` for `Mutex<dyn base_engine::DataSet>`
Run Code Online (Sandbox Code Playgroud)

我尝试["rc"]向 serde 添加功能,但这没有帮助。

Cha*_*man 6

更新:从 serde 1.0.145 开始,此代码有效。


原答案:

Serde 不支持序列化Mutex未调整大小的类型。我发送了一个 PR 来放松这一点,但与此同时你可以使用新类型:

pub struct MutexWrapper<T: ?Sized>(pub Mutex<T>);

impl<T: ?Sized + Serialize> Serialize for MutexWrapper<T> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        self.0
            .lock()
            .expect("mutex is poisoned")
            .serialize(serializer)
    }
}

let x: Arc<MutexWrapper<dyn DataSet>> = Arc::new(MutexWrapper(Mutex::new(data)));
Run Code Online (Sandbox Code Playgroud)

当然,您仍然需要启用rc的功能。serde