You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需自定义反序列化器,如何为含Weak的Rust结构体传入Arc完成反序列化?

无需自定义反序列化器给结构体注入Weak引用的方法

你可以通过两种简单方式实现需求,完全不需要编写自定义反序列化器或访问器:

方法一:利用serde的字段跳过属性

给SomeState中的b字段添加#[serde(skip_deserializing)]属性,让serde在反序列化时忽略这个字段,之后手动为其赋值为传入Arc的Weak引用:

use serde::Deserialize;
use std::sync::{Arc, Weak};
use serde_json;

struct SomeGlobal;

#[derive(Deserialize)]
struct SomeState {
    pub a: i32,
    #[serde(skip_deserializing)]
    pub b: Weak<SomeGlobal>,
}

fn magic_deserialize(value: serde_json::Value, g: Arc<SomeGlobal>) -> Result<SomeState, serde_json::Error> {
    let mut state = serde_json::from_value(value)?;
    state.b = Arc::downgrade(&g);
    Ok(state)
}

#[test]
fn example() {
    let g = Arc::new(SomeGlobal);
    let value = serde_json::json!({
        "a": 5
    });

    let state = magic_deserialize(value, g.clone()).unwrap();

    assert_eq!(state.a, 5);
    assert!(state.b.upgrade().is_some());
}

这个属性会告诉serde不要尝试从JSON输入中读取b字段,反序列化完成后我们直接替换成需要的Weak引用即可。

方法二:使用临时结构体过渡

定义一个只包含需要从JSON反序列化字段的临时结构体,反序列化完成后用它的数据和传入的Arc构造最终的SomeState:

use serde::Deserialize;
use std::sync::{Arc, Weak};
use serde_json;

struct SomeGlobal;

#[derive(Deserialize)]
struct SomeState {
    pub a: i32,
    pub b: Weak<SomeGlobal>,
}

#[derive(Deserialize)]
struct TempState {
    pub a: i32,
}

fn magic_deserialize(value: serde_json::Value, g: Arc<SomeGlobal>) -> Result<SomeState, serde_json::Error> {
    let temp_state = serde_json::from_value(value)?;
    Ok(SomeState {
        a: temp_state.a,
        b: Arc::downgrade(&g),
    })
}

#[test]
fn example() {
    let g = Arc::new(SomeGlobal);
    let value = serde_json::json!({
        "a": 5
    });

    let state = magic_deserialize(value, g.clone()).unwrap();

    assert_eq!(state.a, 5);
    assert!(state.b.upgrade().is_some());
}

这种方式拆分了反序列化和结构体构造的逻辑,适合结构体字段较多的场景。

内容的提问来源于stack exchange,提问作者A.Z.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:55:25