首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >把东西(移动)放进结构中会产生寿命错误。

把东西(移动)放进结构中会产生寿命错误。
EN

Stack Overflow用户
提问于 2020-06-04 06:04:22
回答 1查看 178关注 0票数 3

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

代码语言:javascript
复制
#[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,
        })
    }

以下是完整的错误:

代码语言:javascript
复制
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

代码语言:javascript
复制
let socket_set = SocketSet::new(vec![]);

为变量提供此类型:

代码语言:javascript
复制
virtual_tun::interface::smoltcp::socket::SocketSet<'a, 'static, 'static>

好的,SocketSet的生存期SocketSet,如下所定义:

代码语言:javascript
复制
    pub struct SocketSet<'a, 'b: 'a, 'c: 'a + 'b> {
        sockets: ManagedSlice<'a, Option<Item<'b, 'c>>>
    }

存储在ManagedSlice中的东西的生存期,即Option<Item<'b, 'c>>

因此,我传递给SocketSet构造函数的匿名SocketSet被转换为具有生存期'a的片的引用,并且片内的东西具有static生存期。不知道为什么但他们有。我想问题是,它要求'bSmolStack应该是'static

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-04 07:05:16

这是因为socketsSocketSet::new中存在生存期限制。ManagedSlice要求它的价值与'a 从其定义上看 ManagedSlice<'a, T: 'a>一样长。

泛型约束SocketsT: Into<ManagedSlice<'a, Option<Item<'b, 'c>>>并不断言ManagedSliceOwned。因此,无论into返回Owned还是Borrowed,编译器都将确保这段代码工作正常。ManagedSlice必须寿命最长的ManagedSlice::OwnedManagedSlice::Borrowed,因为它可能是。

在本例中,调用.into() on sockets确实会创建一个ManagedSlice::Owned,但是在into返回ManagedSlice::Borrowed的情况下,into将创建一个引用。因此,它使'a至少与'static一样长,因为sockets是函数的所有者,a是对sockets的引用。

更改泛型约束以明确传递的内容不是引用,就可以消除警告。

代码语言:javascript
复制
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())
        }
    }
}

如果将代码修改为

代码语言:javascript
复制
sockets: ManagedSlice::from(sockets.into())

因为同样,还不清楚from是返回Owned还是Borrowed

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

代码语言:javascript
复制
#[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())
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62187855

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档