Rust面试题及详细答案120道(01-10)-- 基础语法与数据类型

发布于:2025-08-14 ⋅ 阅读:(26) ⋅ 点赞:(0)

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux… 。

前后端面试题-专栏总目录

在这里插入图片描述

一、本文面试题目录

1. 简述Rust的基本数据类型有哪些,与其他语言相比有何特点?

Rust的基本数据类型可分为标量类型复合类型

  • 标量类型:包括整数(如i32u64)、浮点数(f32f64)、布尔值(bool)、字符(char,占4字节,支持Unicode)。
  • 复合类型:包括元组(tuple,固定长度)、数组(array,固定长度且元素类型相同)。

特点

  • 强类型且类型安全,编译期严格检查类型匹配。
  • 无隐式类型转换(如i32不能直接转为i64,需显式使用as)。
  • 字符类型默认支持Unicode(如可表示中文、 emoji),而部分语言(如C)的char仅支持ASCII。
  • 数组和元组长度固定,确保内存布局可预测,与动态数组(Vec)形成互补。

示例

let a: i32 = 42;         // 有符号32位整数
let b: f64 = 3.14;       // 64位浮点数
let c: bool = true;      // 布尔值
let d: char = '😀';      // Unicode字符
let t: (i32, &str) = (10, "hello"); // 元组
let arr: [i32; 3] = [1, 2, 3];      // 数组

2. Rust中letlet mut的区别是什么?为什么默认不可变?

  • let:用于声明不可变变量,一旦赋值后不能修改其值。
  • let mut:用于声明可变变量,允许后续修改其值。

默认不可变的原因
Rust的设计理念强调内存安全和可预测性。默认不可变可减少意外修改导致的bug,尤其在多线程环境中能避免数据竞争。同时,不可变变量的内存布局更稳定,有助于编译器优化。

示例

let x = 5;
// x = 6;  // 编译错误:不能修改不可变变量

let mut y = 10;
y = 20;  // 正确:可变变量可修改

3. 解释Rust的标量类型(Scalar Types),包括整数、浮点数、布尔值和字符的具体分类。

标量类型代表单个值,Rust的标量类型分类如下:

  1. 整数类型

    • 按位长分:8/16/32/64/128位,以及平台相关的isize(指针大小)和usize(索引大小)。
    • 按符号分:i(有符号,如i32)和u(无符号,如u64)。
    • 示例:i8(-128127)、`u32`(04294967295)。
  2. 浮点数类型

    • f32:32位单精度浮点数。
    • f64:64位双精度浮点数(默认浮点数类型)。
    • 示例:let pi: f64 = 3.1415926;
  3. 布尔值(bool

    • 仅两个可能值:truefalse,占1字节。
    • 示例:let is_ok: bool = 5 > 3;
  4. 字符(char

    • 占4字节,支持Unicode标量值(范围:U+0000`U+D7FF`和`U+E000`U+10FFFF)。
    • 可表示字母、数字、符号、emoji等。
    • 示例:let c: char = 'A'; let emoji: char = '🦀';

4. 什么是复合类型(Compound Types)?举例说明元组(Tuple)和数组(Array)的用法及区别。

复合类型:将多个值组合成一个类型,Rust中主要有元组和数组。

  • 元组(Tuple)

    • 长度固定,元素类型可不同。
    • 用法:用括号包裹逗号分隔的元素,可通过索引或解构访问。
    • 示例:
      let tuple: (i32, &str, f64) = (42, "hello", 3.14);
      println!("{}", tuple.0); // 访问第一个元素:42
      
      // 解构元组
      let (a, b, c) = tuple;
      println!("{} {} {}", a, b, c); // 42 hello 3.14
      
  • 数组(Array)

    • 长度固定,所有元素类型必须相同。
    • 用法:用中括号包裹,格式为[类型; 长度],通过索引访问。
    • 示例:
      let arr: [i32; 4] = [1, 2, 3, 4];
      println!("{}", arr[2]); // 访问第三个元素:3
      
      let filled_arr = [0; 5]; // 初始化5个0的数组:[0,0,0,0,0]
      

区别

特性 元组(Tuple) 数组(Array)
元素类型 可不同 必须相同
访问方式 索引(.0)或解构 索引([0]
长度灵活性 编译期固定,但元素类型灵活 编译期固定,类型单一

5. Rust中字符串有String&str两种类型,它们的区别是什么?如何相互转换?

  • &str:字符串切片,是对已分配字符串的不可变引用,存储在栈上,包含指向数据的指针和长度。通常用于引用字符串字面量(如"hello"),无所有权。
  • String:动态字符串,存储在堆上,可增长或修改,拥有其数据的所有权。

区别

类型 存储位置 可变性 所有权 典型用途
&str 栈(引用) 不可变 引用字符串字面量或切片
String 可变 动态创建/修改字符串

相互转换

  • String&str:通过引用转换(&s)或as_str()方法。
  • &strString:通过to_string()方法或String::from()函数。

示例

// &str 转 String
let s_str: &str = "hello";
let s_string1 = s_str.to_string();
let s_string2 = String::from(s_str);

// String 转 &str
let my_string = String::from("world");
let my_str1: &str = &my_string;
let my_str2 = my_string.as_str();

6. 解释Option<T>枚举的作用,它解决了什么问题?与其他语言的null有何不同?

Option<T>枚举用于表示一个值可能存在(Some(T))或不存在(None),定义如下:

enum Option<T> {
    Some(T),
    None,
}

作用

  • 显式标记可能为空的值,避免“空指针异常(NPE)”。
  • 强制开发者在使用前处理“无值”的情况,确保类型安全。

解决的问题
其他语言(如Java、C#)中的null是一个特殊值,可赋值给任何引用类型,但访问null会导致运行时错误。Option<T>将“空”作为枚举的一个变体,编译期强制检查是否处理了None,避免意外访问空值。

null的区别

  • Option<T>是类型系统的一部分,编译器确保对其值的访问必须先判断是否为SomeNone
  • null是运行时概念,编译器无法提前检测错误。

示例

let some_number: Option<i32> = Some(5);
let no_number: Option<i32> = None;

// 必须处理None的情况(编译期检查)
match some_number {
    Some(n) => println!("Number: {}", n),
    None => println!("No number"),
}

7. Result<T, E>枚举的用途是什么?如何处理其中的错误(使用matchif let?运算符)?

Result<T, E>枚举用于表示操作可能成功(Ok(T))或失败(Err(E)),定义如下:

enum Result<T, E> {
    Ok(T),    // 成功时包含的值
    Err(E),   // 失败时的错误信息
}

用途

  • 替代异常处理机制,显式处理错误,避免意外崩溃。
  • 常用于文件操作、网络请求等可能失败的场景。

错误处理方式

  1. match匹配:完整处理OkErr

    let result: Result<i32, &str> = Ok(42);
    match result {
        Ok(val) => println!("Success: {}", val),
        Err(e) => println!("Error: {}", e),
    }
    
  2. if let简化匹配:仅处理一种情况(如只关心错误)。

    let result: Result<i32, &str> = Err("Failed");
    if let Err(e) = result {
        println!("Error occurred: {}", e);
    }
    
  3. ?运算符:快速传播错误(仅用于返回Result的函数)。

    fn divide(a: i32, b: i32) -> Result<i32, String> {
        if b == 0 {
            return Err("Division by zero".to_string());
        }
        Ok(a / b)
    }
    
    fn calculate() -> Result<i32, String> {
        let res = divide(10, 0)?; // 若错误则直接返回Err
        Ok(res)
    }
    

8. 什么是范围(Range)?....=有何区别?举例说明其在循环中的应用。

范围(Range) 是表示值序列的语法糖,常用于迭代。Rust中有两种范围:

  • start..end:左闭右开范围,包含start,不包含end[start, end))。
  • start..=end:全包含范围,包含startend[start, end])。

在循环中的应用
范围常与for循环配合,用于迭代数值序列。

示例

// 1..5:包含1、2、3、4(不含5)
for i in 1..5 {
    print!("{} ", i); // 输出:1 2 3 4
}

// 1..=5:包含1、2、3、4、5
for i in 1..=5 {
    print!("{} ", i); // 输出:1 2 3 4 5
}

// 配合数组索引
let arr = [10, 20, 30, 40];
for i in 0..arr.len() {
    println!("{}", arr[i]); // 遍历数组元素
}

9. Rust的注释有哪几种类型?文档注释(/////!)的作用是什么?

Rust的注释类型包括:

  1. 单行注释//,注释从//到行尾。

    let x = 5; // 这是一个单行注释
    
  2. 多行注释/* ... */,可跨多行。

    /* 这是一个
       多行注释 */
    let y = 10;
    
  3. 文档注释:用于生成API文档(通过rustdoc工具),分为两种:

    • ///:为其下方的项(如函数、结构体)生成文档。
    • //!:为其所在的模块(mod)生成文档。

文档注释示例

//! 这是一个数学工具模块(模块级文档)

/// 计算两个数的和(函数级文档)
/// # 示例
/// ```
/// let result = add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

运行cargo doc --open可生成HTML文档并查看。

10. 解释Rust的变量遮蔽(Shadowing),与mut有何区别?

变量遮蔽(Shadowing):使用let关键字声明与已存在变量同名的新变量,新变量会“遮蔽”旧变量,旧变量不再可访问。

特点

  • 新变量可与旧变量类型不同。
  • 旧变量的生命周期在新变量声明时结束。

mut的区别

特性 变量遮蔽(Shadowing) mut(可变变量)
语法 使用let重新声明同名变量 声明时加mut,修改时直接赋值
类型 新变量可与旧变量类型不同 类型必须保持一致
可变性 旧变量仍不可变,只是被遮蔽 变量本身可修改值

示例

// 变量遮蔽
let x = 5;
let x = x + 1; // 新x遮蔽旧x,类型仍为i32
let x = "now I'm a string"; // 新x类型为&str,遮蔽前一个x

// mut变量
let mut y = 5;
y = y + 1; // 正确:修改可变变量
// let y = "string"; // 若不加let则错误,因类型不匹配

遮蔽常用于临时转换变量类型或修改值但保持不可变语义的场景。

二、120道Rust面试题目录列表

文章序号 Rust面试题120道
1 Rust面试题及详细答案120道(01-10)
2 Rust面试题及详细答案120道(11-18)
3 Rust面试题及详细答案120道(19-26)
4 Rust面试题及详细答案120道(27-32)
5 Rust面试题及详细答案120道(33-41)
6 Rust面试题及详细答案120道(42-50)
7 Rust面试题及详细答案120道(51-57)
8 Rust面试题及详细答案120道(58-65)
9 Rust面试题及详细答案120道(66-71)
10 Rust面试题及详细答案120道(72-80)
11 Rust面试题及详细答案120道(81-89)
12 Rust面试题及详细答案120道(90-98)
13 Rust面试题及详细答案120道(99-105)
14 Rust面试题及详细答案120道(106-114)
15 Rust面试题及详细答案120道(115-120)

网站公告

今日签到

点亮在社区的每一天
去签到