我正在实现一个类似于栈的结构,其中该结构持有对切片的可变引用。
我希望能够弹出该堆栈的最后一个元素,类似于以下方式:
struct StackLike<'a, X> {
data: &'a mut [X],
}
我希望能够弹出该堆栈的最后一个元素,类似于以下方式:
impl<'a, X> StackLike<'a, X> {
pub fn pop(&mut self) -> Option<&'a X> {
if self.data.is_empty() {
return None;
}
let n = self.data.len();
let result = &self.data[n - 1];
self.data = &mut self.data[0..n - 1];
Some(result)
}
}
这个失败了:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/lib.rs:11:23
|
11 | let result = &self.data[n - 1];
| ^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
--> src/lib.rs:6:5
|
6 | / pub fn pop(&mut self) -> Option<&'a X> {
7 | | if self.data.is_empty() {
8 | | return None;
9 | | }
... |
13 | | Some(result)
14 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:11:23
|
11 | let result = &self.data[n - 1];
| ^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 5:6...
--> src/lib.rs:5:6
|
5 | impl<'a, X> StackLike<'a, X> {
| ^^
note: ...so that the expression is assignable
--> src/lib.rs:13:9
|
13 | Some(result)
| ^^^^^^^^^^^^
= note: expected `std::option::Option<&'a X>`
found `std::option::Option<&X>`
即使是返回值简化、仅缩小切片的pop
的简化版本也无效。
impl<'a, X> StackLike<'a, X> {
pub fn pop_no_return(&mut self) {
if self.data.is_empty() {
return;
}
let n = self.data.len();
self.data = &mut self.data[0..n - 1];
}
}
这提供了
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/lib.rs:11:26
|
11 | self.data = &mut self.data[0..n - 1];
| ^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
--> src/lib.rs:6:5
|
6 | / pub fn pop_no_return(&mut self) {
7 | | if self.data.is_empty() {
8 | | return;
9 | | }
10 | | let n = self.data.len();
11 | | self.data = &mut self.data[0..n - 1];
12 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:11:26
|
11 | self.data = &mut self.data[0..n - 1];
| ^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 5:6...
--> src/lib.rs:5:6
|
5 | impl<'a, X> StackLike<'a, X> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:11:21
|
11 | self.data = &mut self.data[0..n - 1];
| ^^^^^^^^^^^^^^^^^^^^^^^^
有没有办法让这个工作起来,或者我需要更明确地跟踪我感兴趣的切片的范围?
self.data
初始为空,则“临时”替换的切片最终将变成永久性的(因为当split_last_mut
返回None
时,你会失去原始切片)。实际上,这可能不是问题,因为所有空切片都多多少少是等价的,但如果你在处理数据地址时做了一些棘手的事情,它可能会导致意外。 - trentpop
的返回类型不需要持有可变引用,即:pub fn pop(&mut self) -> Option<&'a X>
。 - Peter Halldata
可以是&'a [X]
,这个问题就会变得更容易一些。 - kreo