为何Rust冒泡排序代码报cannot borrow `arr[_]`多次可变借用错误
问题原因
- 借用规则冲突:Rust安全规则禁止对同一数组同时持有多个可变引用,当前编译器无法自动识别
&mut arr[j]和&mut arr[j+1]是两个完全不重叠的独立内存引用,因此判定为非法的二次可变借用,触发E0499报错。 - 隐含的传值逻辑错误:当前
bubble_sort采用值传递接收数组,函数内部操作的是原数组的副本,即使编译通过,main函数中打印的原数组也不会有任何排序后的变化。
修复方案
最简便的修复方式是直接使用Rust标准库为数组/切片内置的swap方法,标准库内部已经处理了借用合法性校验,不需要自行实现swap函数:
fn main() { println!("Sort numbers ascending"); // 添加mut关键字,允许后续可变修改 let mut num:[i32; 10] = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1]; println!("Before: {:?}", num); // 传入可变引用,直接修改原数组 bubble_sort(&mut num); println!("After: {:?}\n", num); } fn bubble_sort(arr: &mut [i32]) { // 参数改为可变切片,支持任意长度的数组输入,适用性更强 for i in 0..arr.len() { for j in 0..arr.len() - 1 - i { if arr[j] > arr[j + 1] { // 调用内置swap方法,自动处理借用冲突 arr.swap(j, j + 1); } } } }
如果需要保留自定义swap的实现,可以按照编译器提示使用split_at_mut获取两个不重叠的可变子切片,再分别取出对应位置的引用传入swap函数:
// 自定义swap函数保持不变 fn swap( a: &mut i32, b: &mut i32){ let tmp: i32 = *b; *b=*a; *a=tmp; } fn bubble_sort(arr: &mut [i32]) { for i in 0..arr.len() { for j in 0..arr.len() - 1 - i { if arr[j] > arr[j + 1] { // 用split_at_mut切割为两个不重叠的子切片 let (left, right) = arr.split_at_mut(j+1); swap(&mut left[j], &mut right[0]); } } } }
内容的提问来源于stack exchange,提问作者Tom Tom
相关产品推荐
相关产品推荐

