简体   繁体   English

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

[英]Derive `Deserialize` with borrowed struct field

I'm trying to derive Deserialize on a struct that has borrowed content:我正在尝试在已借用内容的结构上派生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,
}

rust playground 锈游乐场

I get the following compilation error:我收到以下编译错误:

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`

What are the different ways I can get this struct to implement Deserialize for some lifetime ?我可以通过哪些不同的方式让这个结构在某个生命周期内实现Deserialize

Note: I don't actually require the deserialization to be zero-copy, it's only a nice-to-have注意:我实际上并不要求反序列化为零复制,这只是一个很好的选择

You can't do this, and here's why:你不能这样做,原因如下:

Serde allows for zero-copy deserialization of certain types. Serde 允许对某些类型进行零拷贝反序列化。 In this case, the data is borrowed from the Deserializer , which in turn either borrows or owns a buffer of some kind.在这种情况下,数据是从Deserializer借用的,而Deserializer又借用或拥有某种缓冲区。 Since &[u8] and &str are both fundamentally streams of bytes, they can just be deserialized as references into the buffer.由于&[u8]&str基本上都是字节流,因此它们可以作为引用反序列化到缓冲区中。 How exactly this works is explained in the serde docs , but it fundamentally requires that the Rust type is laid out exactly as the data exists in the buffer you are deserializing. serde docs 中解释了这是如何工作的,但它从根本上要求 Rust 类型的布局与您正在反序列化的缓冲区中存在的数据完全一致。

In your case, however, you want to deserialize a SocketAddr .但是,在您的情况下,您想要反序列化SocketAddr The problem is that the data in the buffer is in a different form from the data you want to borrow.问题在于缓冲区中的数据与您要借用的数据的形式不同。 Serde serializes a SocketAddr s into a string via Display , see for example this implemention for SocketAddrV4 . Serde 通过DisplaySocketAddr序列化为字符串,例如参见SocketAddrV4 实现 But a SocketAddr itself is stored as a 32 bit integer and a 16 bit integer.但是SocketAddr本身存储为 32 位整数和 16 位整数。 You cannot borrow one as the other;你不能借一个作为另一个; some kind of parsing needs to happen, and someone then needs to own the resulting data.需要进行某种解析,然后有人需要拥有结果数据。 Serde logically has your struct own that data. Serde 逻辑上让您的结构拥有该数据。 Even in binary serialization, there is no guarantee the layout of the serialized data will match the layout of the struct, so parsing needs to happen.即使在二进制序列化中,也不能保证序列化数据的布局与结构的布局相匹配,因此需要进行解析。

This is encoded in the type system via the implementations of Deserialize serde provides.这是通过Deserialize serde 提供的实现在类型系统中编码的。 This page has the full list. 此页面有完整列表。 You can see that there is an implementation for &'a str where the lifetime of the Deserializer ( 'de ) outlives 'a .你可以看到,有一个实施&'a str ,其中的寿命Deserializer'de )会超越'a There is no implementation for references to most other types, including &SocketAddr .大多数其他类型的引用没有实现,包括&SocketAddr

This serde issue linked by PitaJ shows a good minimal code example. PitaJ链接的这个 serde 问题显示了一个很好的最小代码示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Rust:如何为具有泛型类型的结构派生反序列化? - Rust: how to derive Deserialize for struct with generic types? 为什么 struct 字段的借用时间比预期的长 - Why is a struct field borrowed longer than expected 为什么Serde无法为仅包含&Path的结构派生反序列化? - Why can Serde not derive Deserialize for a struct containing only a &Path? 无法分配给结构字段,因为它已被借用,但借用的字段位于单独的 scope - Cannot assign to struct field because it is already borrowed, yet borrowed field is in separate scope 从结构中获取枚举字段:无法移出借来的内容 - Get an enum field from a struct: cannot move out of borrowed content 如何修改 Rust 中借用结构的字段? - How do I modify a borrowed struct's field in Rust? Rust:将借来的结构传递给借来的枚举? - Rust: Passing borrowed struct to a borrowed enum? 使用`#[derive(Debug)]`覆盖结构的单个字段的默认实现 - Override the default implementation for a single field of a struct using `#[derive(Debug)]` 如果没有实现 Copy 或 Clone 特征,那么重用借用的结构字段的最佳方法是什么? - What is the best way to reuse a borrowed struct field if it doesn't implement the Copy or Clone trait? 从struct字段分配变量时“无法移出借来的内容” - “cannot move out borrowed content” when assigning a variable from a struct field
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM