为什么Serde默认情况下不支持Rc和Arc类型? [英] Why does Serde not support Rc and Arc types by default?

查看:248
本文介绍了为什么Serde默认情况下不支持Rc和Arc类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请说明Serde rc功能

Please explain the Serde rc feature

Rc<T>Arc<T>选择加入impls.序列化和反序列化 这些类型不会保留身份,并可能导致多种 相同数据的副本.确保这是您想要的 启用此功能.

Opt into impls for Rc<T> and Arc<T>. Serializing and deserializing these types does not preserve identity and may result in multiple copies of the same data. Be sure that this is what you want before enabling this feature.

序列化包含引用计数指针的数据结构 每次 指针在数据结构内被引用.序列化将 不要尝试对这些重复的数据进行重复数据删除.

Serializing a data structure containing reference-counted pointers will serialize a copy of the inner value of the pointer each time a pointer is referenced within the data structure. Serialization will not attempt to deduplicate these repeated data.

反序列化包含引用计数指针的数据结构 不会尝试对相同数据进行重复数据删除.每一个 反序列化的指针最终将具有1的强计数.

Deserializing a data structure containing reference-counted pointers will not attempt to deduplicate references to the same data. Every deserialized pointer will end up with a strong count of 1.

为什么此功能标志存在,为什么它不是默认行为?

Why does this feature flag exist and why isn't it default behaviour? What does it mean by

对这些类型进行序列化和反序列化不会保留身份,并且可能导致同一数据的多个副本

Serializing and deserializing these types does not preserve identity and may result in multiple copies of the same data

我知道它与 Serde问题194 有关. 问题的最新消息

如果您想确保自己不会偶然以包含rc的派生impl结尾,请打开clippy问题.

If you want to make sure you don't accidentally end up with a derived impl containing an rc, open a clippy issue.

功能标记是否存在以捕获Rc结构的意外用法?

Does the feature flag exist to catch unexpected usages of an Rc struct?

推荐答案

中所述Serde问题194 ,将反序列化为RcArc的实现的缺点是:

As stated in Serde issue 194, the drawbacks of the implementation of deserializing to Rc or Arc are:

  • 可能会增加内存使用量
  • 基于地址中断比较的平等比较
  • 内部可变性未反映在副本中

功能标志文档中对此有所呼应:

This is echoed in the feature flag documentation:

串行化不会尝试对这些重复的数据进行重复数据删除.

Serialization will not attempt to deduplicate these repeated data.

对包含引用计数指针的数据结构进行反序列化将不会尝试对相同数据的引用进行重复数据删除.

Deserializing a data structure containing reference-counted pointers will not attempt to deduplicate references to the same data.

RcArc的通常点是共享数据.反序列化为包含RcArc的结构时,不会发生这种共享.在此示例中,创建了5个完全不同的Rc<str>,彼此互不相关,即使它们都具有相同的内容:

The usual point of an Rc or Arc is to share data. This sharing doesn't happen when deserializing to a struct containing Rc or Arc. In this example, 5 completely distinct Rc<str>s are created with no relation to each other, even though they all have the same content:

use std::{rc::Rc, ptr};

fn main() {
    let json = r#"[
        "alpha",
        "alpha",
        "alpha",
        "alpha",
        "alpha"
    ]"#;

    let strings = serde_json::from_str::<Vec<Rc<str>>>(json).unwrap();
    
    dbg!(ptr::eq(strings[0].as_ref(), strings[1].as_ref()));
}

[src/main.rs:14] ptr::eq(strings[0].as_ref(), strings[1].as_ref()) = false

当您具有内部可变性的Rc<RefCell<_>>或其他类型时,这尤其糟糕,因为您可能希望修改其中一个项目会修改项目的 all .

This is especially bad when you have an Rc<RefCell<_>> or other type with interior mutability, as you might expect that modifying one of the items modifies all of the items.

另请参阅:

  • Is there a way to distingush between different `Rc`s of the same value?
  • How can I get Serde to allocate strings from an arena during deserialization?

这篇关于为什么Serde默认情况下不支持Rc和Arc类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆