as_mut().unwrap():由于需求冲突,无法推断生命周期
as_mut().unwrap(): Cannot infer lifetime due to conflicting requirements
Rust 生命周期再次让我感到困惑。我正在尝试 return 对我拥有的盒装对象的可变引用。这是我的简化问题:
pub trait Foo {
fn foo(&self);
}
pub struct Bar {
foo: Option<Box<Foo>>,
}
impl Bar {
pub fn foo(&mut self) -> &mut Box<Foo> {
let foo_ref = self.foo.as_mut();
foo_ref.unwrap()
}
pub fn set_foo(&mut self, value: Box<Foo>) {
self.foo = Some(value);
}
}
我收到这些错误,但我不太明白:
Compiling testproject v0.0.1 (file:///home/virtlink/projects/orion/testproject)
src/lib.rs:15:17: 15:25 error: cannot infer an appropriate lifetime due to conflicting requirements
src/lib.rs:15 foo_ref.unwrap()
^~~~~~~~
src/lib.rs:15:9: 15:25 note: first, the lifetime cannot outlive the method call at 15:8...
src/lib.rs:15 foo_ref.unwrap()
^~~~~~~~~~~~~~~~
src/lib.rs:15:9: 15:16 note: ...so that method receiver is valid for the method call
src/lib.rs:15 foo_ref.unwrap()
^~~~~~~
src/lib.rs:13:44: 16:6 note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the block at 13:43...
src/lib.rs:13 pub fn foo(&mut self) -> &mut Box<Foo> {
src/lib.rs:14 let foo_ref = self.foo.as_mut();
src/lib.rs:15 foo_ref.unwrap()
src/lib.rs:16 }
src/lib.rs:15:9: 15:25 note: ...so that expression is assignable (expected `&mut Box<Foo>`, found `&mut Box<Foo>`)
src/lib.rs:15 foo_ref.unwrap()
^~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `testproject`.
我不知道如何解决这个问题。
这是一个生命周期省略的案例,默认对象以一种令人痛苦的不可见方式限制适得其反。
错误是完全不透明的,这是不好的。如果将 .as_mut().unwrap()
替换为可比较的 match
语句:
match self.foo {
Some(ref mut foo) => foo,
None => panic!(),
}
事情变得更清楚了:
a.rs:13:34: 13:37 error: mismatched types:
expected `&mut Box<Foo>`,
found `&mut Box<Foo>`
(lifetime mismatch) [E0308]
a.rs:13 Some(ref mut foo) => foo,
^~~
a.rs:11:44: 16:6 note: the anonymous lifetime #1 defined on the block at 11:43...
a.rs:11 pub fn foo(&mut self) -> &mut Box<Foo> {
a.rs:12 match self.foo {
a.rs:13 Some(ref mut foo) => foo,
a.rs:14 None => panic!(),
a.rs:15 }
a.rs:16 }
note: ...does not necessarily outlive the static lifetime
error: aborting due to previous error
现在我们知道正在发生的是类型 &mut Box<Foo>
中某处的生命周期不匹配,即匿名生命周期不一定比静态生命周期长。这种类型有两个生命周期;没有类型省略,该类型是 &'a mut Box<Foo + 'b>
。请记住,对于特征对象,您仍然需要指示特征对象可以持续多长时间,因此 'b
。在最常见的情况下,Box<Trait>
等同于 Box<Trait + 'static>
,这表明特征对象不能包含任何非静态引用。 (如果没有这种保证,内存安全就会受到破坏。)在您的结构定义中,特征对象的生命周期以这种方式推断为 'static
。
然而,Box<Trait>
中省略的生命周期并不总是被解释为 'static
。如果它包含在引用中,则所需的生命周期将缩短为该值,即 &'a Box<Trait>
被解释为 &'a Box<Trait + 'a>
.
因此,您方法的完整无省略签名实际上是这样的:
pub fn foo<'a>(&'a mut self) -> &'a mut Box<Foo + 'a>;
现在我不清楚为什么这不起作用;我本以为可以将 &'a mut Box<Foo + 'static>
(您拥有的)强制转换为 &'a mut Box<Foo + 'a>
,但显然情况并非如此;它 可能 是差异处理中的错误(拒绝应该合法的代码)或者它可能不是,我不确定。我不明白为什么匿名生命周期 #1 需要比静态生命周期长,这个错误感觉就像是在处理生命周期。
无论如何,您真正想要的是返回 &'a mut Box<Foo + 'static>
。所以只要明确地写出 'static
就可以了:
pub fn foo(&mut self) -> &mut Box<Foo + 'static> {
self.foo.as_mut().unwrap()
}
另一种解决方案是在定义中要求实现 Foo
的类型必须始终是 'static
。然后 Box<Foo + 'a>
对于一个不一定和 'static
一样大的 'a
显然是胡说八道,它变得明智并且知道它必须是 'static
。 (特征的任何生命周期约束都会覆盖默认对象边界。)
您可以在 RFC 599 中阅读有关默认对象边界的更多信息。
Rust 生命周期再次让我感到困惑。我正在尝试 return 对我拥有的盒装对象的可变引用。这是我的简化问题:
pub trait Foo {
fn foo(&self);
}
pub struct Bar {
foo: Option<Box<Foo>>,
}
impl Bar {
pub fn foo(&mut self) -> &mut Box<Foo> {
let foo_ref = self.foo.as_mut();
foo_ref.unwrap()
}
pub fn set_foo(&mut self, value: Box<Foo>) {
self.foo = Some(value);
}
}
我收到这些错误,但我不太明白:
Compiling testproject v0.0.1 (file:///home/virtlink/projects/orion/testproject)
src/lib.rs:15:17: 15:25 error: cannot infer an appropriate lifetime due to conflicting requirements
src/lib.rs:15 foo_ref.unwrap()
^~~~~~~~
src/lib.rs:15:9: 15:25 note: first, the lifetime cannot outlive the method call at 15:8...
src/lib.rs:15 foo_ref.unwrap()
^~~~~~~~~~~~~~~~
src/lib.rs:15:9: 15:16 note: ...so that method receiver is valid for the method call
src/lib.rs:15 foo_ref.unwrap()
^~~~~~~
src/lib.rs:13:44: 16:6 note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the block at 13:43...
src/lib.rs:13 pub fn foo(&mut self) -> &mut Box<Foo> {
src/lib.rs:14 let foo_ref = self.foo.as_mut();
src/lib.rs:15 foo_ref.unwrap()
src/lib.rs:16 }
src/lib.rs:15:9: 15:25 note: ...so that expression is assignable (expected `&mut Box<Foo>`, found `&mut Box<Foo>`)
src/lib.rs:15 foo_ref.unwrap()
^~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `testproject`.
我不知道如何解决这个问题。
这是一个生命周期省略的案例,默认对象以一种令人痛苦的不可见方式限制适得其反。
错误是完全不透明的,这是不好的。如果将 .as_mut().unwrap()
替换为可比较的 match
语句:
match self.foo {
Some(ref mut foo) => foo,
None => panic!(),
}
事情变得更清楚了:
a.rs:13:34: 13:37 error: mismatched types:
expected `&mut Box<Foo>`,
found `&mut Box<Foo>`
(lifetime mismatch) [E0308]
a.rs:13 Some(ref mut foo) => foo,
^~~
a.rs:11:44: 16:6 note: the anonymous lifetime #1 defined on the block at 11:43...
a.rs:11 pub fn foo(&mut self) -> &mut Box<Foo> {
a.rs:12 match self.foo {
a.rs:13 Some(ref mut foo) => foo,
a.rs:14 None => panic!(),
a.rs:15 }
a.rs:16 }
note: ...does not necessarily outlive the static lifetime
error: aborting due to previous error
现在我们知道正在发生的是类型 &mut Box<Foo>
中某处的生命周期不匹配,即匿名生命周期不一定比静态生命周期长。这种类型有两个生命周期;没有类型省略,该类型是 &'a mut Box<Foo + 'b>
。请记住,对于特征对象,您仍然需要指示特征对象可以持续多长时间,因此 'b
。在最常见的情况下,Box<Trait>
等同于 Box<Trait + 'static>
,这表明特征对象不能包含任何非静态引用。 (如果没有这种保证,内存安全就会受到破坏。)在您的结构定义中,特征对象的生命周期以这种方式推断为 'static
。
然而,Box<Trait>
中省略的生命周期并不总是被解释为 'static
。如果它包含在引用中,则所需的生命周期将缩短为该值,即 &'a Box<Trait>
被解释为 &'a Box<Trait + 'a>
.
因此,您方法的完整无省略签名实际上是这样的:
pub fn foo<'a>(&'a mut self) -> &'a mut Box<Foo + 'a>;
现在我不清楚为什么这不起作用;我本以为可以将 &'a mut Box<Foo + 'static>
(您拥有的)强制转换为 &'a mut Box<Foo + 'a>
,但显然情况并非如此;它 可能 是差异处理中的错误(拒绝应该合法的代码)或者它可能不是,我不确定。我不明白为什么匿名生命周期 #1 需要比静态生命周期长,这个错误感觉就像是在处理生命周期。
无论如何,您真正想要的是返回 &'a mut Box<Foo + 'static>
。所以只要明确地写出 'static
就可以了:
pub fn foo(&mut self) -> &mut Box<Foo + 'static> {
self.foo.as_mut().unwrap()
}
另一种解决方案是在定义中要求实现 Foo
的类型必须始终是 'static
。然后 Box<Foo + 'a>
对于一个不一定和 'static
一样大的 'a
显然是胡说八道,它变得明智并且知道它必须是 'static
。 (特征的任何生命周期约束都会覆盖默认对象边界。)
您可以在 RFC 599 中阅读有关默认对象边界的更多信息。