rust - 如何获得持久的`Vec.last()` 指针?
问题描述
我正在尝试用 Rust 构建一个虚拟机,但我遇到了(我认为是)一个基本的生命周期问题。
以下是VM的相关部分:
#[derive(Copy, Clone)]
enum Value<'v> {
Bool(bool),
Str(&'v str),
Empty,
}
// Updated VM
struct VM<'vm> {
values: Vec<Value<'vm>>,
// `VM.strings` will keep references to "result" strings, like those from `concat`.
strings: Vec<String>,
}
impl<'vm> VM<'vm> {
// Pushes the given value onto the stack.
// Returns the index of the value.
fn push_value(&mut self, value: Value<'vm>) -> usize {
self.values.push(value);
return self.values.len() - 1;
}
fn get_value(&self, index: usize) -> Value<'vm> {
// Assume the best of our users...
return unsafe { *self.values.get_unchecked(index) };
}
fn concat(&mut self, i1: usize, i2: usize) -> usize {
let first = self.get_value(i1);
let second = self.get_value(i2);
let result = match (first, second) {
(Value::Str(v1), Value::Str(v2)) => [v1, v2].concat(),
_ => panic!("Attempted to CONCAT non-strings."),
};
self.strings.push(result);
let result_ptr = self.strings.last().unwrap();
self.push_value(Value::Str(result_ptr))
}
}
我正在尝试concat
为两个字符串编写一个操作。这是我的尝试:
Rust 编译器给了我一个我不完全理解的详细错误:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/lib.rs:38:39
|
38 | let result_ptr = self.strings.last().unwrap();
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 29:5...
--> src/lib.rs:29:5
|
29 | / fn concat(&mut self, i1: usize, i2: usize) -> usize {
30 | | let first = self.get_value(i1);
31 | | let second = self.get_value(i2);
32 | | let result = match (first, second) {
... |
39 | | self.push_value(Value::Str(result_ptr))
40 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/lib.rs:38:26
|
38 | let result_ptr = self.strings.last().unwrap();
| ^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'vm` as defined on the impl at 16:6...
--> src/lib.rs:16:6
|
16 | impl<'vm> VM<'vm> {
| ^^^
note: ...so that the types are compatible
--> src/lib.rs:39:14
|
39 | self.push_value(Value::Str(result_ptr))
| ^^^^^^^^^^
= note: expected `&mut VM<'_>`
found `&mut VM<'vm>`
一些杂七杂八的想法:
- 该错误似乎与
last()
指针的生命周期有关。我想我理解这一点:因为您可以从 a 中删除元素Vec
,所以last()
指针仅在短时间内有效(在您的函数内)。我知道我不会从中删除元素VM.strings
:有没有办法告诉编译器? - 我考虑过将 enum 变体更改为
Str(String)
, 但随后Value
将不再Copy
,我认为这是寄存器值的一个重要特征。另外,因为我不会改变String
值,所以感觉&str
这里是更“正确”的选择?
解决方案
推荐阅读
- bash - shell:如何用包含空格的新字符串替换字符串
- python - 根据现有模型字段数据在 Django 中对 QuerySet 进行排序和排名,仅限于前几个排名?
- python - 在使用按钮从数据库中删除行时需要帮助
- python - 在 Flask 应用程序中从 PDF 文件中提取文本
- importerror - 精益 3 立即挂起导入语句
- nginx - 非云 k8s 集群中具有静态 IP 地址的入口控制器
- grpc - 暴露网络上的 gRPC
- javascript - 想要将嵌套的 for 循环转换为递归,
- html - 如何将不同长度的文本 flexbox 元素与固定大小的 iframe flexbox 元素对齐?
- html - 网页大小比预期高两倍