我正在开发一个 Rust 项目,使用 rusb 与 USB 设备交互。我面临生命周期管理问题,无法返回包含引用的结构,因为它引用嵌套循环中的局部变量。这是导致问题的简化代码:
下面提供的代码片段是
rusb crate
的一部分,它是一个用于在 Rust 中处理 USB 通信的第三方库。
pub struct InterfaceDescriptors<'a> {
iter: slice::Iter<'a, libusb_interface_descriptor>,
}
impl<'a> Iterator for InterfaceDescriptors<'a> {
type Item = InterfaceDescriptor<'a>;
fn next(&mut self) -> Option<InterfaceDescriptor<'a>> {
self.iter.next().map(|descriptor| InterfaceDescriptor { descriptor })
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
pub struct InterfaceDescriptor<'a> {
descriptor: &'a libusb_interface_descriptor,
}
这是我的箱子中的代码片段:
use rusb::{Device, Context, UsbContext};
pub struct ABC<'a> {
/// Descriptor of the USB interface.
usb_interface_descriptor: &'a rusb::InterfaceDescriptor<'a>,
}
impl<'a> ABC<'a> {
pub fn find_compatible_device(
usb_device: &'a Device<Context>,
) -> anyhow::Result<Option<ABC<'a>>, rusb::Error> {
let dev_descriptor = usb_device.device_descriptor()?;
for cfg_index in 0..dev_descriptor.num_configurations() {
let cfg_descriptor = usb_device.config_descriptor(cfg_index)?;
for interface in cfg_descriptor.interfaces() {
for descriptor in interface.descriptors() {
// <!------ Error occurs here ------>
return Ok(Some(ABC {
usb_interface_descriptor: &descriptor,
}));
}
}
}
Ok(None)
}
}
usb_interface_descriptor
无法克隆。我知道 cfg_descriptor
在循环末尾被删除,使得对其内容的任何引用无效。
我正在尝试返回
ABC
的实例,其中包含对 InterfaceDescriptor
的引用。但是,我收到以下编译错误:
error[E0515]: cannot return value referencing local variable `cfg_descriptor`
--> src/test.rs:20:28
|
17 | for interface in cfg_descriptor.interfaces() {
| -------------- `cfg_descriptor` is borrowed here
...
20 | return Ok(Some(ABC {
| ____________________________^
21 | | usb_interface_descriptor: &descriptor,
22 | | }));
| |_______________________^ returns a value referencing data owned by the current function
error[E0515]: cannot return value referencing local variable `descriptor`
--> src/test.rs:20:28
|
20 | return Ok(Some(ABC {
| ____________________________^
21 | | usb_interface_descriptor: &descriptor,
| | ----------- `descriptor` is borrowed here
22 | | }));
| |_______________________^ returns a value referencing data owned by the current function
重构此代码以避免生命周期问题同时仍从函数返回必要数据的最佳方法是什么?
看定义
pub struct InterfaceDescriptor<'a> {
descriptor: &'a libusb_interface_descriptor,
}
InterfaceDescriptor 只是引用的一个薄包装器,因此尝试避免复制它(通过使用引用)不会获得太多好处。
我只是定义 ABC 来直接保存 InterfaceDescriptor(而不是对它的引用)。