问题
Please explain the Serde rc
feature
Opt into impls for
Rc<T>
andArc<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.
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
I know that it is related to Serde issue 194. The last message of the issue says
If you want to make sure you don't accidentally end up with a derived impl containing an rc, open a clippy issue.
Does the feature flag exist to catch unexpected usages of an Rc
struct?
回答1:
As stated in Serde issue 194, the drawbacks of the implementation of deserializing to Rc
or Arc
are:
- Potentially increased memory usage
- Equality comparison that relies on comparison of address breaks
- Interior mutability is not reflected in copies
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.
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
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.
See also:
- 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?
来源:https://stackoverflow.com/questions/60604346/why-does-serde-not-support-rc-and-arc-types-by-default