代码之家  ›  专栏  ›  技术社区  ›  Walter Svenddal

Rust serde序列化到Vec或从Vec序列化到HashMap

  •  1
  • Walter Svenddal  · 技术社区  · 6 月前

    我有一个JSON集合,其中包含我想来回序列化为列表表示的映射元素。这是我写的代码:

    use serde::{de::DeserializeOwned, Deserialize, Serialize};
    use std::{collections::HashMap, hash::Hash};
    
    pub trait GetId<T>
    {
        fn get_id(&self) -> &T;
    }
    
    /// Serializable collection
    #[derive(Serialize, Deserialize, Default, Clone)]
    #[serde(from="Vec<V>", into="Vec<V>")]
    pub struct Collection<K, V>
    where K: Eq + Hash + Clone,
          V: Serialize + DeserializeOwned + GetId<K> + Clone,
    {
        data: HashMap<K, V>,
    }
    
    impl<K, V> Collection<K, V>
    where K: Eq + Hash + Clone,
          V: Serialize + DeserializeOwned + GetId<K> + Clone,
    {
        pub fn new() -> Self {
            Collection {
                data: HashMap::new(),
            }
        }
    
        pub fn insert(&mut self, item: V) -> Option<V> {
            let id = item.get_id().to_owned();
            self.data.insert(id, item)
        }
    }
    
    impl<K, V> From<Vec<V>> for Collection<K, V>
    where K: Eq + Hash + Clone,
          V: Serialize + DeserializeOwned + GetId<K> + Clone,
    {
        fn from(value: Vec<V>) -> Self {
            let mut obj: Collection<K, V> = Collection::new();
            value.into_iter().for_each(|v| { obj.insert(v); });
            obj
        }
    }
    
    impl<K, V> Into<Vec<V>> for Collection<K, V>
    where K: Eq + Hash + Clone,
          V: Serialize + DeserializeOwned + GetId<K> + Clone,
    {
        fn into(self) -> Vec<V> {
            Vec::from_iter(self.data.into_values())
        }
    }
    

    我用 From<Vec<V>> 实施和 GetKey<K> trait插入序列化的所有元素 Vec<V> 进入 HashMap<K, V> .

    然而,我在这里遇到了生命周期问题,并出现了以下错误:

    error[E0283]: type annotations needed: cannot satisfy `V: Deserialize<'_>`
      --> src\idls\collection.rs:14:12
       |
    14 | pub struct Collection<K, V>
       |            ^^^^^^^^^^^^^^^^
       |
    note: multiple `impl`s or `where` clauses satisfying `V: Deserialize<'_>` found
      --> src\idls\collection.rs:12:21
       |
    12 | #[derive(Serialize, Deserialize, Default, Clone)]
       |                     ^^^^^^^^^^^
    ...
    17 |     V: Serialize + DeserializeOwned + GetId<K> + Clone,
       |                    ^^^^^^^^^^^^^^^^
    note: required for `Collection<K, V>` to implement `Deserialize<'de>`
      --> src\idls\collection.rs:12:21
       |
    12 | #[derive(Serialize, Deserialize, Default, Clone)]
       |                     ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
    13 | #[serde(from="Vec<V>", into="Vec<V>")]
    14 | pub struct Collection<K, V>
       |            ^^^^^^^^^^^^^^^^
       = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
    
    
    

    我对Rust不够熟悉,无法理解我在这里做错了什么。我通读了 Deserializer lifetimes Serde提供的文档,但我不太理解为什么这些泛型似乎不起作用。我试过交换 DeserializeOwned 具有 for<'a> Deserialize<'a> ,但我不认为这对我的用例是正确的,而且它也不起作用。

    1 回复  |  直到 6 月前
        1
  •  2
  •   BallpointBen    6 月前

    衍生 Serialize Deserialize 将自动为泛型参数添加必要的特性边界,因此您不应该自己编写它们。所以,只要删除 Serialize + DeserializeOwned 从特质界限 V .