如何迭代一个结构体的元素?

12

我正在编写一个用于加密网络通信的小型客户端/服务器程序,并使用以下结构体允许端点协商能力。

struct KeyExchangePacket {
    kexinit: u8,
    replay_cookie: [u8; 32],
    kex_algorithms: String,
    kgen_algorithms: String,
    encryption_algorithms: String,
    mac_algorithms: String,
    compression_algorithms: String,
    supported_languages: String,
}

为了通过 TcpStream 发送这些字段,我需要将它们转换为字节,但目前我只能每次转换一个。

send_buffer.extend_from_slice(kex_algorithms.as_bytes());
send_buffer.extend_from_slice(kgen_algorithms.as_bytes());
etc...

有没有一种方法可以迭代字段并将它们的字节值推入缓冲区以便发送?

2个回答

12

有没有一种方法可以遍历结构体的字段?

没有。你必须自己实现它,或者找到一个宏/编译器插件来为你完成。

参见如何迭代或映射元组?类似的问题。

想一想迭代器是如何工作的。迭代器必须在每次迭代中产生一个单独的类型。对于由至少3种不同类型组成的结构体,那个类型会是什么呢?


1
如果编译器插件/nightly可行的话,Serde可能非常有用。 - mcarton
1
@mcarton 你知道有没有适用于通用字节的serde适配器吗?或者你认为OP需要自己编写这样的适配器? - Shepmaster
1
你的意思是什么?Serde本身可以从Vec <u8>序列化/反序列化。 - mcarton
1
@mcarton 很有意思!我之前以为 serde 可以使用 JSON、XML 或 MessagePack 将结构体输出到 Vec<u8> 中,但并不知道还有一种模式可以将结构体的所有字节合并在一起。那么,如果我想让 serde 输出 OP 的数据而不附带任何序列化格式,该如何实现呢? - Shepmaster

3

Bincode这样做。

let packet = KeyExchangePacket { /* ... */ };
let size_limit = bincode::SizeLimit::Infinite;
let encoded: Vec<u8> = bincode::serde::serialize(&packet, size_limit).unwrap();

从自述文件中:

编码(以及解码)的过程毫不意外 - 原始类型根据底层 Writer 进行编码,元组和结构体通过逐个编码其字段进行编码,枚举通过首先写出表示变体的标记,然后是内容进行编码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接