【发布时间】:2022-01-23 03:20:30
【问题描述】:
struct Population<'a> {
dat: Vec<Genotype<'a>>,
}
impl<'a> Population<'a> {
fn new(dat: Vec<Genotype<'a>>) -> Self {
Population { dat }
}
fn select(&self) -> Genotype {
self.dat.first().unwrap().clone()
}
}
#[derive(Clone)]
struct Genotype<'a> {
data: &'a str,
}
impl<'a> Genotype<'a> {
fn new(data: &'a str) -> Self {
Genotype { data }
}
}
fn main() {
let hello = "Hello World";
let genotype = Genotype::new(hello);
let mut population = Population::new(vec![genotype]);
let other = population.select();
drop(population);
println!("{}", other.data);
}
编译器声称population不能被删除,因为它是在other中借用的:
error[E0505]: cannot move out of `population` because it is borrowed
--> src/main.rs:32:10
|
31 | let other = population.select();
| ------------------- borrow of `population` occurs here
32 | drop(population);
| ^^^^^^^^^^ move out of `population` occurs here
33 | println!("{}", other.data);
| ---------- borrow later used here
我看不出这两个变量是如何相互关联的。我怀疑错误出在select 函数中,因为这显然是借用的来源。
我尝试为 select (fn select<'b>(&self) -> Genotype<'b>) 添加单独的生命周期,但失败了,因为我认为编译器假定 Population 实例的生命周期与返回的 Genotype 有某种联系,即使它涉及到内部&str。
我到底做错了什么?
【问题讨论】:
-
这很难解释,play.rust-lang.org/…,最好的建议不要这样做,生命周期对 rust 初学者没有用处,只是不要在你的结构中使用参考。把事情简单化。如果您确实需要分享内容,请使用
Rc。 -
我刚刚尝试过,编译器只是提示我应该将匿名生命周期添加到
select函数(fn select(&self) -> Genotype<'_>),但错误仍然存在。 -
@Stargateur 感谢您的帮助,这很有效。所以基本上这只是告诉编译器生命周期是专门链接到内部
&str而不是一些匿名生命周期,这有点正确吗? -
@Shepmaster 啊,我现在明白你的意思了,谢谢!
标签: rust borrow-checker