特征界限 `&'a chain::Chain<'a>: Deserialize<'_>` 不满足

the trait bound `&'a chain::Chain<'a>: Deserialize<'_>` is not satisfied

我是 Rust 的新手,我想从 children 访问 parent 结构。 我想使用它的孩子 Chain.blocks 中的 Chain。 所以我试图存储对 parent Chain.

的引用

但是我遇到了这个错误。

the trait bound `&'a chain::Chain<'a>: Deserialize<'_>` is not satisfied
the following implementations were found:
  <chain::Chain<'a> as Deserialize<'de>>rustcE0277

这是我的代码。

// Chain
#[derive(Default, Serialize, Deserialize)]
pub struct Chain<'a> {
    pub blocks: Vec<Block<'a>>,
}

// Block
#[derive(Deserialize, Serialize)]
pub struct Block<'a> {
    pub id: String,
    pub prev_hash: String,
    pub timestamp: u64,
    pub nonce: i32,
    pub proof: String,
    pub miner: String,
    pub documents: Vec<String>,
    pub merkel_root: String,
    chain: &'a Chain<'a>,
}

impl<'a> Default for Block<'a> {
    fn default() -> Self {
        Self {
            ..Default::default()
        }
    }
}

对不起,如果我回复得太晚了。

问题

你想做的是一个 self-referential 结构,这在 Rust 中很麻烦。例如,参见 个答案。这不一定是不可能的,但如果您尝试为您的数据找到不同的模型,那将是最好的。

另外:serde的派生机制不关心你的字段是否是pub,它无论如何都会反序列化到它。而且它无法知道您希望 chain 包含对其父项的引用。实际上,它会为块生成一个解串器,可以使用stand-alone。如果你按照@PitaJ 的建议(chain: Box<Chain>)去做,你会得到一个反序列化器,它需要像

这样的数据
{
  "id": "foo",
  …
  "merkel_root": "You're thinking of Merkle, Merkel is the German chancellor a. D.",
  "chain": {
    "blocks": [
      {
        "id": "bar",
        …
        "chain": {
          "blocks": []
        }
      }
    ]
  }
}

最后:

impl<'a> Default for Block<'a> {
    fn default() -> Self {
        Self {
            ..Default::default()
        }
    }
}

是无限递归。但是如果你设法克服编译器错误,rustc 会警告你。

warning: function cannot return without recursing
  --> src/lib.rs:25:5
   |
25 |     fn default() -> Self {
   |     ^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
26 |         Self {
27 |             ..Default::default()
   |               ------------------ recursive call site
   |

如果你绝对想要这个

…反对更好的建议,然后你可以通过引用计数(和我的favourite serde trick)得到一些接近的东西:

首先,你需要解决serde在Block中不知道在chain中存储什么的问题。您可以将其设为 Option 并将其标记为 #[serde(skip)],但我更喜欢使用第二个结构,其中仅包含您实际想要反序列化的字段:

#[derive(Deserialize)]
pub struct ChainSerde {
    pub blocks: Vec<BlockSerde>,
}

#[derive(Deserialize)]
pub struct BlockSerde {
    pub id: String,
    // … - doesn't contain chain
}

您想要使用的实际结构如下所示

#[derive(Deserialize, Serialize, Debug)]
#[serde(from = "ChainSerde")]
pub struct Chain {
    pub blocks: Rc<RefCell<Vec<Block>>>,
}

#[derive(Debug, Serialize)]
pub struct Block {
    pub id: String,
    // …
    #[serde(skip)] // Serialization would crash without
    // If you wanted Chain instead of Vec<Block>, you'd need another
    // #[serde(transparent, from = "ChainSerde")]
    // struct ChainParent(Rc<RefCell<Chain>>)
    chain: Weak<RefCell<Vec<Block>>>,
}

现在,您需要做的就是告诉 serde 如何将反序列化的结构转换为您实际想要使用的结构。

impl From<ChainSerde> for Chain {
    fn from(t: ChainSerde) -> Self {
        let b: Rc<RefCell<Vec<Block>>> = Default::default();
        let bc: Vec<Block> = t
            .blocks
            .into_iter()
            .map(|block| Block {
                id: block.id,
                chain: Rc::downgrade(&b),
            })
            .collect::<Vec<Block>>();
        *RefCell::borrow_mut(&b) = bc;
        Chain { blocks: b }
    }
}

如果你想等待 Rust 1.60,你可以使用 Rc::new_cyclic:

#[derive(Deserialize, Debug)]
#[serde(from = "ChainSerde")]
pub struct ChainNightly {
    pub blocks: Rc<Vec<BlockNightly>>,
}

#[derive(Debug)]
pub struct BlockNightly {
    pub id: String,
    // …
    chain: Weak<Vec<BlockNightly>>,
}

impl From<ChainSerde> for ChainNightly {
    fn from(t: ChainSerde) -> Self {
        ChainNightly {
            blocks: Rc::new_cyclic(|blocks| {
                t.blocks
                    .into_iter()
                    .map(|block| BlockNightly {
                        id: block.id,
                        chain: blocks.clone(),
                    })
                    .collect()
            }),
        }
    }
}

Playground