使用借用的结构字段派生“反序列化”

Nic*_*all 2 macros traits rust deserialization

我试图派生出Deserialize一个借用了内容的结构:

#[macro_use]
extern crate serde_derive;
use std::net::SocketAddr;

#[derive(Hash, Eq, PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct MyS<'a> {
    pub addr: &'a SocketAddr,
}
Run Code Online (Sandbox Code Playgroud)

锈游乐场

我收到以下编译错误:

error[E0277]: the trait bound `&'a std::net::SocketAddr: _::_serde::Deserialize<'_>` is not satisfied
 --> src/lib.rs:7:5
  |
7 |     pub addr: &'a SocketAddr,
  |     ^^^ the trait `_::_serde::Deserialize<'_>` is not implemented for `&'a std::net::SocketAddr`
  |
  = help: the following implementations were found:
            <std::net::SocketAddr as _::_serde::Deserialize<'de>>
  = note: required by `_::_serde::de::SeqAccess::next_element`
Run Code Online (Sandbox Code Playgroud)

我可以通过哪些不同的方式让这个结构在Deserialize一生中实现?

注意:我实际上并不要求反序列化为零复制,这只是一个很好的选择

Lyt*_*gas 5

你不能这样做,原因如下:

Serde 允许对某些类型进行零拷贝反序列化。在这种情况下,数据是从 借用的Deserializer,而后者又借用或拥有某种缓冲区。由于&[u8]&str基本上都是字节流,因此可以将它们反序列化为缓冲区中的引用。serde docs 中解释了这是如何工作的,但它从根本上要求 Rust 类型的布局与您正在反序列化的缓冲区中存在的数据完全一致。

但是,在您的情况下,您想要反序列化SocketAddr. 问题在于缓冲区中的数据与您要借用的数据的形式不同。SERDE串行化一个SocketAddrs转换为字符串通过Display,例如见这个FPGA实现SocketAddrV4。但是 aSocketAddr本身存储为 32 位整数和 16 位整数。你不能借一个作为另一个;需要进行某种解析,然后有人需要拥有结果数据。Serde 逻辑上让您的结构拥有该数据。即使在二进制序列化中,也不能保证序列化数据的布局与结构的布局匹配,因此需要进行解析。

这是通过Deserializeserde 提供的实现在类型系统中编码的。此页面有完整列表。您可以看到有一个实现( )&'a str的生命周期长于何处。对大多数其他类型的引用没有实现,包括.Deserializer'de'a&SocketAddr

PitaJ链接的这个 serde 问题显示了一个很好的最小代码示例。