Rust中为何元组可同时获取各元素的可变引用,而数组却不行?
Rust中为何元组可同时获取各元素的可变引用,而数组却不行?
这个问题问得特别精准,刚好触及了Rust借用检查器处理不同复合类型时的核心逻辑差异,我来给你掰扯清楚:
首先说元组的情况:
元组的每个元素都是编译期就明确的独立字段,w.0和w.1在内存中是完全不重叠的两个位置,编译器一眼就能确定这俩是八竿子打不着的两块内存。所以当你分别获取它们的可变引用时,完全符合Rust“同一时间不能有多个可变引用指向同一块内存”的安全规则——毕竟它们根本不是同一块啊!所以借用检查器直接放行,编译毫无压力。
然后看数组的情况:
数组的索引访问是通过IndexMut trait实现的,这里的关键在于:编译器没办法在编译期100%确认w[0]和w[1]一定指向不同的内存。举个例子,如果你的索引不是字面量0、1,而是两个变量i和j,那谁也没法保证i != j对吧?为了绝对保证内存安全,Rust的借用检查器会采取保守策略:只要是通过数组索引获取可变引用,就默认认为这些引用可能指向同一块内存,哪怕你用的是看起来完全不同的字面量索引。所以它会拒绝这种同时存在多个可变引用的情况,直接抛出编译错误。
如果想让数组的这段代码正常编译,其实也有办法——用Rust标准库提供的、能明确划分不相交内存区域的方法,比如split_first_mut或者split_at_mut:
fn main() { let mut w = [107, 109]; let (w0, rest) = w.split_first_mut().unwrap(); let w1 = &mut rest[0]; *w0 = 110; *w1 = 111; println!("{}", w0); println!("{}", w1); println!("{:?}", w); }
这些方法的内部实现已经向编译器证明了返回的可变引用指向的是数组中完全不相交的部分,所以借用检查器就会放行啦。
备注:内容来源于stack exchange,提问作者sai manohar
相关产品推荐
相关产品推荐

