MST

星途 面试题库

面试题:Rust向量安全访问的边界情况处理

假设你有一个Rust向量`vec: Vec<i32>`,编写一段代码来安全地访问向量中倒数第二个元素,如果向量长度小于2则返回`None`。要求使用`try_into`或`checked_sub`等安全的方式来处理索引计算,阐述为何这样能保障安全。
31.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
fn get_second_last(vec: &Vec<i32>) -> Option<&i32> {
    let len = vec.len();
    if len < 2 {
        return None;
    }
    let index = (len.checked_sub(1)?).checked_sub(1)?;
    vec.get(index)
}

安全性阐述

  1. checked_sub:在计算倒数第二个元素的索引时,len.checked_sub(1) 首先计算倒数第一个元素的索引。如果 len0checked_sub 会返回 None,这意味着索引计算失败,从而函数直接返回 None,避免了越界访问。同样,(len.checked_sub(1)?).checked_sub(1) 确保在获取倒数第二个元素的索引时,如果 len 小于 2,也会返回 None,进而函数返回 None,保障了安全性。
  2. getvec.get(index) 使用 get 方法来获取元素,get 方法会在索引越界时返回 None,而不是像 vec[index] 那样导致程序 panic,这进一步确保了代码在处理可能越界的索引时的安全性。

如果使用 try_into,可以这样实现:

fn get_second_last(vec: &Vec<i32>) -> Option<&i32> {
    let len = vec.len();
    if len < 2 {
        return None;
    }
    let index: usize = (len - 2).try_into().ok()?;
    vec.get(index)
}

安全性阐述

  1. try_into(len - 2).try_into()len - 2 的结果尝试转换为 usize 类型。如果 len - 2 是负数(即 len 小于 2),try_into 会返回 Errok() 将其转换为 None,函数返回 None,避免了越界风险。同样,后续的 vec.get(index) 进一步保障了安全性。