gpt4 book ai didi

rust - 当Foobar具有正好一个字段时,直接将Vec >反序列化为Vec

转载 作者:行者123 更新时间:2023-12-03 11:48:18 25 4
gpt4 key购买 nike

我得到了一种数据格式,其中包括一系列对象,每个对象都有一个命名字段value。反序列化时可以删除此间接层吗?

反序列化时,自然表示为

/// Each record has it's own `{ value: ... }` object
#[derive(serde::Deserialize)]
struct Foobar<T> {
value: T,
}

/// The naive representation, via `Foobar`...
#[derive(serde::Deserialize)]
struct FoobarContainer {
values: Vec<Foobar<T>>,
}

尽管 Foobar除了 T之外没有增加任何额外的成本,但我想在类型级别上删除此间接层:
#[derive(serde::Deserialize)]
struct FoobarContainer {
values: Vec<T>,
}

可以从 Foobar中删除 FoobarContainer,同时仍通过反序列化使用它吗?

最佳答案

在一般情况下,没有简单的方法可以进行这种转换。为此,请查看以下现有答案:

  • How do I write a Serde Visitor to convert an array of arrays of strings to a Vec<Vec<f64>>?
  • How to transform fields during deserialization using Serde?

  • 在本示例中,第一个是我的常规入门解决方案和 looks like this

    但是,在您的特定情况下,您说:

    objects with exactly one named field value



    您已经确定了一个关键要求:

    While Foobar adds no extra cost beyond T



    这意味着您可以使 Foobar具有 transparent representation并使用 不安全Rust Rust 在类型之间进行转换(尽管 not actually with mem::transmute ):
    struct FoobarContainer<T> {
    values: Vec<T>,
    }

    #[derive(serde::Deserialize)]
    #[repr(transparent)]
    struct Foobar<T> {
    value: T,
    }

    impl<'de, T> serde::Deserialize<'de> for FoobarContainer<T>
    where
    T: serde::Deserialize<'de>,
    {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
    D: serde::Deserializer<'de>,
    {
    let mut v: Vec<Foobar<T>> = serde::Deserialize::deserialize(deserializer)?;

    // I copied this from Stack Overflow without reading the surrounding
    // text that describes why this is actually safe.
    let values = unsafe {
    let data = v.as_mut_ptr() as *mut T;
    let len = v.len();
    let cap = v.capacity();

    std::mem::forget(v);

    Vec::from_raw_parts(data, len, cap)
    };

    Ok(FoobarContainer { values })
    }
    }

    也可以看看:
  • How do I convert a Vec<T> to a Vec<U> without copying the vector?
  • 关于rust - 当Foobar具有正好一个字段时,直接将Vec <Foobar <T >>反序列化为Vec <T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62754344/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com