首先,我知道创建最小可重现性示例要好得多,但我不知道这个问题从何而来。我已经清除了这个问题的大部分密码。
#[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>好的,SocketSet的生存期SocketSet,如下所定义:
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生存期。不知道为什么但他们有。我想问题是,它要求'b从SmolStack应该是'static
ps:我无法控制SocketSet、SocketSet::new等.
发布于 2020-06-04 07:05:16
这是因为sockets在SocketSet::new中存在生存期限制。ManagedSlice要求它的价值与'a 从其定义上看 ManagedSlice<'a, T: 'a>一样长。
泛型约束SocketsT: Into<ManagedSlice<'a, Option<Item<'b, 'c>>>并不断言ManagedSlice是Owned。因此,无论into返回Owned还是Borrowed,编译器都将确保这段代码工作正常。ManagedSlice必须寿命最长的ManagedSlice::Owned和ManagedSlice::Borrowed,因为它可能是。
在本例中,调用.into() on 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是返回Owned还是Borrowed。
您还可以简化代码之外的许多生命周期,使其更具可读性。
#[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())
}
}
}https://stackoverflow.com/questions/62187855
复制相似问题