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

3

我有一个trait叫做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()
    }
}

现在,在程序/应用中,我正在共享指向trait对象的指针:
let x: Arc<Mutex<dyn DataSet>> = Arc::new(Mutex::new(data));

其中data是任何实现了DataSet的对象。

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

serde_json::to_string(&x)

对于Box而言可以正常工作,但是使用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>`

我尝试将["rc"]特性添加到serde中,但这并没有帮助。


很难相信,使用“rc”会得到完全相同的错误消息。 - Finomnis
1
@Finomnis 问题不在于 Arc,而是 serde 对 Mutex 有(隐式)Sized 约束。我正在准备一份 PR。 - Chayim Friedman
很有趣,它居然能够工作(比如,使用 Box)。我的直觉会说你不能序列化一个 dyn。但我猜你只是不能反序列化一个 dyn - Finomnis
1个回答

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)));

当然,您仍需要启用serderc功能。


谢谢!这可能是另一个问题,但 erased_serde 的功能似乎与我的用例密切相关,但我无法找到使用它的任何好处。在我的情况下,erased_serde 有用吗? - Anatoly Bugakov
1
@AnatolyBugakov 不需要使用 dyn Serialize,但 erased-serde 允许您使用它。 - Chayim Friedman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接