Serde分享Arc序列化

Serde share Arc serialization

我正在尝试使用 Serde 将共享引用保存到单个内存位置。我有一个小型结构容器,其中包含两个 Arc<RwLock<f64>> 类型的属性。我的目标是让两个属性共享一个内存位置,这样当我更改一个时,另一个也会更改。这在 main 中创建容器时有效,但是当我加载序列化结构 ref0 和 ref1 不再共享相同的内存位置,并且包含具有相同值的唯一内存位置时。

是否可以向 Serde 指示 ref0 和 ref1 应该共享内存位置并“链接”?

#[derive(Serialize, Deserialize)]
struct Container {
    pub(crate) ref0: Arc<RwLock<f64>>,
    pub(crate) ref1: Arc<RwLock<f64>>
}

保存场景(有效)

//makers ref0 and ref1, assign them to container.
let mut ref0 = Arc::new(RwLock::new(1.0));
let ref1 = ref0.clone();
let container = Container {
    ref0,
    ref1
};

// Checks that changing one ref will alter the other.
mem::replace(&mut *container.ref0.write().unwrap(), 2.0);
println!("{} {}",container.ref0.read().unwrap(), container.ref1.read().unwrap()); // should output "2.0 2.0" and does.
mem::replace(&mut *container.ref0.write().unwrap(), 3.0);
println!("{} {}",container.ref0.read().unwrap(), container.ref1.read().unwrap()); // should output "3.0 3.0" and does.

// Serializes the struct and save
let f_name = "SaveTest.test";
let mut file = File::create( f_name).unwrap();
let _result = file.write_all(&bincode::serialize(&container).unwrap());

加载场景(不工作)

//LOAD THE CONTAINER
let mut buffer : Vec<u8> = vec![];
BufReader::new(File::open("SaveTest.test").unwrap()).read_to_end(&mut buffer).unwrap();
let container : Container = bincode::deserialize(&buffer).unwrap();

//Verifies that each ref is the same value when it was saved
println!("{} {}",container.ref0.read().unwrap(), container.ref1.read().unwrap()); // Should output "3.0 3.0" and does
mem::replace(&mut *container.ref0.write().unwrap(), 4.0);
println!("{} {}",container.ref0.read().unwrap(), container.ref1.read().unwrap()); // Should output "4.0 4.0" but outputs "4.0 3.0"

无法使用 Serde 序列化引用。见见

您可以创建一个自定义包装器类型,将反序列化的 Container 值作为 f64,并在内部使用 Arc-s 构建一个适当的实例:

#[derive(Serialize, Deserialize)]
struct ContainerData {
    pub value: f64,
}

struct Container {
    pub(crate) ref0: Arc<RwLock<f64>>,
    pub(crate) ref1: Arc<RwLock<f64>>
}

impl Container {
    fn new(data: ContainerData) -> Self {
        let data_ref = Arc::new(data.value);
        Self {
            ref0: Arc::clone(&data_ref),
            ref1: Arc::clone(&data_ref),
        }
    }
}