gpt4 book ai didi

rust - 将东西(移动)放入结构中会产生生命周期错误

转载 作者:行者123 更新时间:2023-12-03 11:26:33 26 4
gpt4 key购买 nike

首先,我知道创建最少的可重现示例要好得多,但我不知道这个问题从何而来。我已经清除了这个问题的大部分代码。

#[derive(Debug)]
pub struct Item<'a, 'b: 'a> {
socket: Socket<'a, 'b>,
refs: usize
}
#[derive(Debug)]
pub struct SocketSet<'a, 'b: 'a, 'c: 'a + 'b> {
sockets: ManagedSlice<'a, Option<Item<'b, 'c>>>
}

impl<'a, 'b: 'a, 'c: 'a + 'b> SocketSet<'a, 'b, 'c> {
pub fn new<SocketsT>(sockets: SocketsT) -> SocketSet<'a, 'b, 'c>
where SocketsT: Into<ManagedSlice<'a, Option<Item<'b, 'c>>>> {
let sockets = sockets.into();
Set {
sockets: sockets
}
}

pub struct TunSmolStack<'a, 'b, 'c> {
sockets: SocketSet<'a, 'b, 'c>,
}

impl<'a, 'b, 'c> TunSmolStack<'a, 'b, 'c> {
pub fn new(interface_name: String) -> Result<TunSmolStack<'a, 'b, 'c>, u32> {
let socket_set = SocketSet::new(vec![]);
Ok(TunSmolStack{
sockets: socket_set,
})
}

这是完整的错误:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
--> src/virtual_tun/smol_stack.rs:26:12
|
26 | Ok(TunSmolStack{
| ^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'b` as defined on the impl at 16:10...
--> src/virtual_tun/smol_stack.rs:16:10
|
16 | impl<'a, 'b, 'c> TunSmolStack<'a, 'b, 'c> {
| ^^
note: ...so that the expression is assignable
--> src/virtual_tun/smol_stack.rs:26:12
|
26 | Ok(TunSmolStack{
| ____________^
28 | | sockets: socket_set,
29 | | })
| |_________^
= note: expected `virtual_tun::smol_stack::TunSmolStack<'_, 'b, 'c>`
found `virtual_tun::smol_stack::TunSmolStack<'_, '_, '_>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `std::option::Option<virtual_tun::interface::smoltcp::socket::SocketSetItem<'_, '_>>` will meet its required lifetime bounds
--> src/virtual_tun/smol_stack.rs:22:26
|
22 | let socket_set = SocketSet::new(vec![]);
| ^^^^^^^^^^^^^^

正在提示SocketSet .好的,可能与 socket_set 的内部对象有关不够生活?为什么要讲静态生命周期?

PS:把我的鼠标放在socket_set上面在

let socket_set = SocketSet::new(vec![]);

为变量提供此类型:

virtual_tun::interface::smoltcp::socket::SocketSet<'a, 'static, 'static>

嗯,一辈子'a对于 SocketSet,定义如下:

    pub struct SocketSet<'a, 'b: 'a, 'c: 'a + 'b> {
sockets: ManagedSlice<'a, Option<Item<'b, 'c>>>
}

是存储在ManagedSlice里面的东西的生命周期,即 Option<Item<'b, 'c>>

所以,匿名vec我传递给 SocketSet 的构造函数转换为对生命周期为 'a 的切片的引用, 切片里面的东西有 static生命周期。不知道为什么,但他们有。我想问题是它需要 'b来自 SmolStack应该是 'static

ps:我无法控制 SocketSet、SocketSet::new 等...

最佳答案

这是因为 sockets 的生命周期限制在 SocketSet::new . ManagedSlice要求它的值(value)与 'a 一样长seen in its definition ManagedSlice<'a, T: 'a> .

通用约束 SocketsT: Into<ManagedSlice<'a, Option<Item<'b, 'c>>>不断言 ManagedSliceOwned .因此,无论 into 是否存在,编译器都会确保此代码有效。返回 OwnedBorrowed . ManagedSlice必须活到最长的生命周期ManagedSlice::OwnedManagedSlice::Borrowed因为它可能是其中之一。

调用 .into()sockets确实创建了一个 ManagedSlice::Owned在这种情况下,但在 into 的情况下返回 ManagedSlice::Borrowed , into会创建一个引用。所以它使'a至少和'static一样长, 作为 sockets由函数和 a 拥有是对 sockets 的引用.

更改通用约束以明确传入的内容不是引用,从而消除警告。

impl<'a, 'b: 'a, 'c: 'a + 'b> SocketSet<'a, 'b, 'c> {
pub fn new<SocketsT>(sockets: SocketsT) -> SocketSet<'a, 'b, 'c>
where SocketsT: Into<Vec<Option<Item<'b, 'c>>>> {
SocketSet {
sockets: ManagedSlice::Owned(sockets.into())
}
}
}

如果将代码修改为,错误将重新出现

sockets: ManagedSlice::from(sockets.into())

因为还是不清楚from将返回 OwnedBorrowed .

您还可以简化代码中的许多生命周期,使其更具可读性。

#[derive(Debug)]
pub struct Item<'a> {
socket: Socket<'a, 'a>,
refs: usize
}
#[derive(Debug)]
pub struct SocketSet<'a> {
sockets: ManagedSlice<'a, Option<Item<'a>>>
}

impl<'a> SocketSet<'a> {
pub fn new<SocketsT>(sockets: SocketsT) -> SocketSet<'a>
where SocketsT: Into<Vec<Option<Item<'a>>>> {
SocketSet {
sockets: ManagedSlice::Owned(sockets.into())
}
}
}

关于rust - 将东西(移动)放入结构中会产生生命周期错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62187855/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com