MST

星途 面试题库

面试题:Rust 数组作为函数参数传递时的注意事项及优化策略

当在 Rust 中将数组作为函数参数传递时,会面临哪些问题?如何通过所有权、借用等机制优化传递过程,以避免性能损耗和内存安全问题?请举例说明。
17.0万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

面临的问题

  1. 所有权转移:默认情况下,当数组作为函数参数传递时,所有权会转移给函数。这意味着原数组在函数外部无法再使用,如果后续代码尝试使用原数组,会导致编译错误。例如:
fn take_array(arr: [i32; 3]) {
    // 这里arr拥有数组的所有权
}

fn main() {
    let my_array = [1, 2, 3];
    take_array(my_array);
    // 这里再使用my_array会报错,因为所有权已转移给take_array函数
    // println!("{:?}", my_array); 
}
  1. 性能损耗:如果数组较大,转移所有权意味着会进行大量数据的复制,这会带来性能开销。

优化方法

  1. 借用
    • 不可变借用:可以通过不可变借用的方式传递数组,这样函数可以读取数组内容,但不会获取所有权,原数组在函数调用后仍然可用。例如:
fn print_array(arr: &[i32]) {
    for num in arr {
        println!("{}", num);
    }
}

fn main() {
    let my_array = [1, 2, 3];
    print_array(&my_array);
    println!("{:?}", my_array); 
}
  • 可变借用:如果函数需要修改数组内容,可以使用可变借用。不过要注意,在同一时间只能有一个可变借用,以避免数据竞争。例如:
fn increment_array(arr: &mut [i32]) {
    for num in arr.iter_mut() {
        *num += 1;
    }
}

fn main() {
    let mut my_array = [1, 2, 3];
    increment_array(&mut my_array);
    println!("{:?}", my_array); 
}
  1. 切片:在 Rust 中,使用切片 &[T] 作为函数参数是一种常见且高效的方式。切片是对数组或动态分配向量的一部分的引用,它不会获取所有权,并且切片的大小是动态的(与固定大小的数组不同),这使得函数可以处理不同长度的数组或向量。例如:
fn sum_slice(slice: &[i32]) -> i32 {
    let mut sum = 0;
    for num in slice {
        sum += num;
    }
    sum
}

fn main() {
    let my_array = [1, 2, 3];
    let result = sum_slice(&my_array);
    println!("Sum: {}", result); 
}

通过上述所有权、借用和切片机制,可以优化数组在函数间传递的过程,避免性能损耗和内存安全问题。