如何在 rust 中返回链接的迭代器



我有一个简单的结构,它定义了某种要通过网络发送的消息。

struct Message {
message_type: u32,
user_id: u32,
message: Vec<u8>,
}

在其他地方,我想将其序列化为一个简单的字节序列。所以我为消息的字节定义了迭代器,如下所示:

impl Message {
fn iter(&self) -> std::iter::Chain<std::iter::Chain<std::slice::Iter<'_, u8>, std::slice::Iter<'_, u8>>, std::slice::Iter<'_, u8>> {
self.message_type
.to_be_bytes()
.iter()
.chain(self.user_id.to_be_bytes().iter())
.chain(self.message.iter())
}
fn data(&self) -> Vec<u8> {
self.iter().cloned().collect()
}
}

是的,该类型随着更多链式迭代器而不断增长,这有点可惜

但是当我尝试运行它时,我收到 2 个编译器错误

cannot return value referencing temporary value
returns a value referencing data owned by the current function. rustc(E0515)

猜猜我对锈的所有权制度不够精通

rust 借用检查器抱怨的问题是to_be_bytes()函数返回一个存储在堆栈上的数组。代码正在尝试为堆栈上分配的对象创建迭代器,并且此迭代器的寿命超过该对象。

self.message_type.to_be_bytes()

例如:
这会在堆栈上创建一个数组,并且.iter()只有在此对象存在时才有效。

有几种方法可以解决此问题。在同一函数中将迭代和最终转换为字节。

fn data(&self) -> Vec<u8> {
self.message_type
.to_be_bytes()
.iter()
.chain(self.user_id.to_be_bytes().iter())
.chain(self.message.iter()).map(|x| *x).collect()
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=129af6e7da3d1e3a9454fffbb124e170

警告: 每当转换为字节时,请确认是否需要小端序/大端序,并且所有字节都遵循相同的字节序。

最新更新