我想定义一个结构,Env它可以选择包含对另一个的(可变)引用Env,称为 it's parent。在所有应用程序中,可以很容易地证明 将会parent比引用更长寿Env。然而,我无法弄清楚如何在类型系统中表达这一点。
我的第一次尝试使我得到了以下结果
struct Env<'a> {
parent: Option<&'a mut Env<'a>>
}
Run Code Online (Sandbox Code Playgroud)
虽然可以编译,但是这两个Env对象现在共享相同的生命周期参数。孩子Env的寿命比孩子短parent,所以这很快就会失败。
我想表达的,大概是这样的:
struct Env<'r> {
parent: Option<&'r mut Env<'e>> where 'e : 'r
}
Run Code Online (Sandbox Code Playgroud)
父级Env有一些(不同的!)生命周期参数'b,该参数比'a确保其安全的参数要长。问题是,如果我们让'e一个参数Env有两个生命周期参数,那么我们又回到了开始的地方。
我正在通过 Crafting Interpreters 进行工作,它使用环境来跟踪解释器中存储的值。对于 Rust 函数的生命周期,我想将给定的环境包装在另一个环境中。函数退出后,新环境将被销毁,并返回原始环境。
我已将其缩减为以下(大部分是最小的)示例。
fn main() {
let mut env = Env {
parent: None,
val: "Global".to_string(),
};
ex_block(3, &mut env); …Run Code Online (Sandbox Code Playgroud) 以下最小示例无法编译:
fn main() {
let mut v = Vec::new();
foo(&mut v);
}
fn foo(v_ref: &mut Vec<u8>) {
for v in v_ref{
println!("{}", v);
}
for v in v_ref{
println!("{}", v);
}
}
Run Code Online (Sandbox Code Playgroud)
编译器建议将第一个 for 循环修改为此,它确实可以编译。
for v in &mut *v_ref{
Run Code Online (Sandbox Code Playgroud)
编译器给出的推理是:
发生 move 是因为
v_ref具有 type&mut Vec<u8>,但它没有实现该Copy特征
v_ref由于隐式调用而移动.into_iter()
问题1:为什么这是必要的?它已经是一个引用了,for 循环在我们完成它之后不应该返回引用吗?
问题 2:为什么修复有效?据我了解,新的可变引用应该使旧的引用无效。