Rust借阅规则疑问:同一作用域可变与不可变引用为何可共存?
你的Rust代码为啥没违反借阅规则?
这事儿的核心是Rust的非词法生命周期(NLL)——编译器不会死抠代码的大括号作用域,而是会追踪每个引用的最后一次使用位置,只要可变引用和不可变引用的实际生效区间不重叠,就不会触发规则冲突。
我们拆开main函数逐段看:
第一段:
change_string(&mut s)和print(&s)let mut s = random(s); change_string(&mut s); // 临时创建的可变引用,用完就失效 print(&s); // 这里的不可变引用是在可变引用失效后才创建的传给
change_string的可变引用,在函数调用结束后就彻底没用了,生命周期到这儿就结束了。后面的不可变引用是在它失效后才生成的,两者压根没重叠,编译器当然放行。第二段:
d、change_string(d)、f和print(f)let d = &mut s; change_string(d); // 这是d的最后一次使用 let f = &s; print(f); // print(d); 注释掉了,d再也没被用到 // change_string(d); 同样注释掉了可变引用
d在change_string(d)调用完之后,就再也没出现在代码里了。编译器能察觉到这一点,所以当你创建不可变引用f的时候,d已经失效了,两者的生命周期没交叉,自然没问题。要是你把注释掉的
print(d)或者change_string(d)取消注释,编译器立刻就会报错——因为这时d的生命周期要延续到这些调用,和f的不可变引用撞在一起了,这才违反了借阅规则。
说白了,Rust的借阅规则管的是“引用的实际使用期有没有重叠”,不是“有没有在同一个大括号里”。NLL让编译器变得更聪明,不用再写很多没必要的作用域拆分代码。
内容的提问来源于stack exchange,提问作者Palash Kanti Kundu
相关产品推荐
相关产品推荐

