如何在 Rust 中 return 链式迭代器
How to return chained iterators in 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 的所有权系统还不够熟悉
rust borrow checker 抱怨的问题是因为 to_be_bytes()
函数 return 一个存储在堆栈上的数组。该代码试图创建一个指向分配在堆栈上的对象的迭代器,而该迭代器的寿命比该对象长。
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()
}
Caution: Whenever you convert to bytes, confirm whether you want little endian/big endian and all the bytes follow the same endianess.
我有一个简单的结构,它定义了某种要通过网络发送的消息。
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 的所有权系统还不够熟悉
rust borrow checker 抱怨的问题是因为 to_be_bytes()
函数 return 一个存储在堆栈上的数组。该代码试图创建一个指向分配在堆栈上的对象的迭代器,而该迭代器的寿命比该对象长。
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()
}
Caution: Whenever you convert to bytes, confirm whether you want little endian/big endian and all the bytes follow the same endianess.