问题描述
我有一段代码需要存储String
并访问对这些字符串的引用。我首先将其编写如下:
struct Pool {
strings : Vec<String>
}
impl Pool {
pub fn new() -> Self {
Self {
strings: vec![]
}
}
pub fn some_f(&mut self) -> Vec<&str> {
let mut v = vec![];
for i in 1..10 {
let string = format!("{}",i);
let string_ref = self.new_string(string);
v.push(string_ref);
}
v
}
fn new_string(&mut self,string : String) -> &str {
self.strings.push(string);
&self.strings.last().unwrap()[..]
}
}
这不会通过借阅检查器:
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/main.rs:19:30
|
14 | pub fn some_f(&mut self) -> Vec<&str> {
| - let's call the lifetime of this reference `'1`
...
19 | let string_ref = self.new_string(string);
| ^^^^ mutable borrow starts here in previous iteration of loop
...
23 | v
| - returning this value requires that `*self` is borrowed for `'1`
因此,借位检查器显然不够智能,无法意识到可变借位不会扩展到对new_string
的调用之外。我尝试从检索引用中分离出使结构发生变化的部分,得到以下代码:
use std::vec::*;
struct Pool {
strings : Vec<String>
}
impl Pool {
pub fn new() -> Self {
Self {
strings: vec![]
}
}
pub fn some_f(&mut self) -> Vec<&str> {
let mut v = vec![];
for i in 1..10 {
let string = format!("{}",i);
self.new_string(string);
}
for i in 1..10 {
let string = &self.strings[i - 1];
v.push(&string[..]);
}
v
}
fn new_string(&mut self,string : String) {
self.strings.push(string);
}
}
这在语义上是等效的(希望如此)并且可以编译。但是,最多要做将两个for
循环组合成一个循环:
for i in 1..10 {
let string = format!("{}",i);
self.new_string(string);
let string = &self.strings[i - 1];
v.push(&string[..]);
}
出现类似的借用错误:
error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
--> src/main.rs:19:13
|
14 | pub fn some_f(&mut self) -> Vec<&str> {
| - let's call the lifetime of this reference `'1`
...
19 | self.new_string(string);
| ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
20 | let string = &self.strings[i - 1];
| ------------ immutable borrow occurs here
...
24 | v
| - returning this value requires that `self.strings` is borrowed for `'1`
我有几个问题:
-
在这种情况下,为什么借位检查器如此严格,以至于在整个循环期间都将可变的借项扩展到整个循环?是否很难/很难分析传递给
&mut
的{{1}}不会在该函数调用之后泄漏? -
是否可以通过自定义生存期来解决此问题,以便我可以返回原来的助手,该助手既变异又返回引用?
-
是否存在一种不同的,更符合Rust惯用的方式,不会让借阅检查器无法实现我想要的目标,即是否具有变异并返回对自身的引用的结构?
我找到了this question,但是我不明白答案(是对#2的否定答案吗?不知道),并且大多数其他问题都存在明确的生命周期参数问题。我的代码仅使用推断的生存期。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)