rust - 为什么 Serde 默认不支持 Rc 和 Arc 类型?
问题描述
请解释一下 Serderc
功能
选择 impls for
Rc<T>
和Arc<T>
. 序列化和反序列化这些类型不会保留身份,并且可能导致相同数据的多个副本。在启用此功能之前,请确保这是您想要的。每次在数据结构中引用指针时,序列化包含引用计数指针的数据结构将序列化指针内部值的副本。序列化不会尝试对这些重复数据进行重复数据删除。
反序列化包含引用计数指针的数据结构不会尝试对相同数据的重复引用进行删除。每个反序列化的指针都会以强计数 1 结束。
为什么这个功能标志存在,为什么它不是默认行为?这是什么意思
序列化和反序列化这些类型不会保留身份,并且可能导致相同数据的多个副本
我知道它与Serde issue 194有关。该问题的最后一条消息说
如果您想确保不会意外地得到包含 rc 的派生 impl,请打开一个 clippy 问题。
是否存在功能标志来捕获Rc
结构的意外用法?
解决方案
如Serde issue 194中所述,反序列化到Rc
or的实现的缺点Arc
是:
- 可能会增加内存使用量
- 依赖于地址中断比较的相等比较
- 内部可变性未反映在副本中
这在功能标志文档中得到了回应:
序列化不会尝试对这些重复数据进行重复数据删除。
反序列化包含引用计数指针的数据结构不会尝试对相同数据的重复引用进行删除。
Rc
or的通常点Arc
是共享数据。Rc
当反序列化为包含or的结构时,不会发生这种共享Arc
。在此示例中,Rc<str>
创建了 5 个完全不同的 s,彼此没有任何关系,即使它们都具有相同的内容:
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<_>>
具有内部可变性的类型或其他类型时,这尤其糟糕,因为您可能期望修改其中一个项目会修改所有项目。
也可以看看:
推荐阅读
- python-3.x - 使用 Gensim 进行动态主题建模/哪个代码?
- javascript - 我已将函数名称“测试”添加到关注中,但错误提示它无法识别为函数。谁能帮助我
- java - 如何在Java中转换字符集?
- jquery - 淘汰赛:未捕获的 ReferenceError:分配中的左侧无效
- javascript - 提交时调用 php 函数,如果可能,不使用 jQuery
- tensorflow - 需要帮助??为 Win 10 Pro 9-2-18 安装 Tensorflow-GPU
- angularjs - 不能在 angularjs 指令中使用 $mdSelect
- c++ - imwrite opencv 会影响捕获时间吗?
- node.js - 将 azure mobileservice 编译为较新版本的 nodejs
- regex - 正则表达式忽略带有部分字符串的单词