MST

星途 面试题库

面试题:Rust match表达式在复杂数据结构中的高效应用

假设有一个自定义的Rust结构体,该结构体包含一个Vec<i32>类型的字段。编写一个函数,使用match表达式对这个结构体进行模式匹配,当Vec为空时,返回0;当Vec只有一个元素时,返回该元素;当Vec有多个元素时,返回它们的总和。同时,解释如何在match表达式中使用解构来访问结构体中的字段,以及如何处理匹配分支中的借用问题。
20.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
struct MyStruct {
    data: Vec<i32>,
}

fn process_struct(s: MyStruct) -> i32 {
    match s.data.len() {
        0 => 0,
        1 => *s.data.first().unwrap(),
        _ => s.data.iter().sum(),
    }
}

解构访问结构体字段

match表达式中,通常可以这样解构结构体:

struct Point {
    x: i32,
    y: i32,
}

fn print_point(p: Point) {
    match p {
        Point { x, y } => println!("x: {}, y: {}", x, y),
    }
}

对于我们题目中的MyStruct,如果要在match表达式中直接解构访问data字段,可以这样写:

fn process_struct_alt(s: MyStruct) -> i32 {
    match s {
        MyStruct { data } => match data.len() {
            0 => 0,
            1 => *data.first().unwrap(),
            _ => data.iter().sum(),
        },
    }
}

处理借用问题

  1. 值捕获:在上面的process_struct函数中,s是按值传递进来的,所以match表达式可以直接消耗MyStruct实例。在每个分支中,data也是按值获取,不存在借用问题。
  2. 借用捕获:如果函数接收的是结构体的引用&MyStruct,例如:
fn process_struct_ref(s: &MyStruct) -> i32 {
    match s.data.len() {
        0 => 0,
        1 => *s.data.first().unwrap(),
        _ => s.data.iter().sum(),
    }
}

这里match表达式处理的是&MyStruct,在分支中data也是借用的。因为iter方法返回的迭代器也只是借用data中的元素,所以sum方法可以正确工作。在这种情况下,要注意生命周期问题,确保借用的生命周期符合Rust的规则。例如,不能在match分支中返回一个指向data内部元素的引用,因为该引用的生命周期会比&MyStruct的生命周期短,会导致悬空引用。