特征界限 `&'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()
}),
}
}
}
我是 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()
}),
}
}
}