以下是涵盖 Rust 核心概念的考试试题,每题均附有详细解析,可用于检验对 Rust 的理解程度。
一、选择题| 题号 | 题目 | 选项 | 答案 | 解析 |
| :--- | :--- | :--- | :--- | :--- |
|1| Rust 中,let x = 5;声明的变量x的默认生命周期是? | A. 作用域内
B. 程序运行期间
C. 静态生命周期
D. 空生命周期 |A| Rust 变量的生命周期默认限定在其声明的作用域(即所在的代码块或函数)内。若需跨作用域或全局使用,需显式标注生命周期。 |
|2|下列哪个特性在 Rust 中用于为泛型参数添加约束条件? | A.where子句
B.impl Trait
C.type别名
D. 标记 trait |A|where子句用于指定泛型类型参数必须实现的 trait 或其他约束,例如fn foo<T>(t: T) where T: Display。impl Trait主要用于简化返回类型或参数类型的书写。 |
|3| Rust 中,unsafe块的主要用途是什么? | A. 优化性能
B. 声明外部函数调用
C. 管理内存安全
D. 实现泛型 |C|unsafe关键字用于标记那些需要绕过 Rust 部分编译期安全检查的代码块,例如操作裸指针、调用外部 C 函数或访问可变静态变量。它允许程序员手动管理内存安全,但使用时必须格外小心,否则可能导致未定义行为。 |
|4| Rust 中,async/await异步编程的实现主要依赖于哪个核心特性? | A.std::thread
B.std::future
C.std::async
D.std::generator|B|async/await语法糖是基于std::future::Futuretrait 构建的。async块或函数会返回一个实现了Future的类型,await则用于暂停当前任务直到Future完成。 |
|5| 以下哪个是 Rust 中实现多线程间安全共享可变状态的推荐模式? | A.std::thread+unsafe共享内存
B.Arc<Mutex<T>>
C.std::sync::atomic
D.std::async+std::thread|B|Arc<T>(原子引用计数)提供多所有权,Mutex<T>提供内部可变性和互斥锁。Arc<Mutex<T>>组合是 Rust 中安全地在多个线程间共享并修改同一数据的标准模式。选项 A 不安全,C 仅适用于原子类型,D 混淆了异步与线程模型。 |
|6| 以下哪个 Rust 特性最有助于在编译期防止空指针解引用错误? | A.Option枚举
B.Result枚举
C.match表达式
D.panic!宏 |A|Option<T>枚举(Some(T)或None)强制开发者显式处理值可能缺失的情况,从类型系统层面消除了空指针问题。Result主要用于错误处理。 |
|7|在 Rust 中,trait关键字主要用于定义什么? | A. 结构体
B. 枚举
C. 接口或行为抽象
D. 模块 |C|trait用于定义一组方法签名,描述类型可以实现的共享行为。它类似于其他语言中的接口,但功能更强大,支持默认实现、关联类型等。 |
|8| Rust 的所有权系统中,用于表示所有权转移的关键词是?(提示:与变量绑定相关) | A.move
B.copy
C.clone
D. (无特定关键词,赋值即转移) |D| 对于实现了Copytrait 的类型(如整数),赋值是复制。对于未实现Copy的类型(如String,Vec),赋值操作会移动所有权,原变量将失效。这是一个语言默认行为,没有特定的转移关键词。 |
二、填空题
- Rust 中,
Option<T>类型用于处理值可能缺失(或为空)的情况。 - 当使用
rayon库进行并行计算时,通常需要确保闭包捕获的数据满足'static生命周期,或者使用Arc等机制来安全地共享数据。 - Rust 中,
match语句必须穷尽所有可能的分支,否则会导致编译错误。 - 在 Rust 的错误处理中,
Result<T, E>枚举用于表示可能失败的操作,其变体为Ok(T)和Err(E)。 - 实现一个 trait 的语法是
impl TraitName for TypeName { ... }。
三、代码分析题
题目:以下代码能否编译通过?如果不能,请指出错误原因;如果能,请写出输出结果。
fn main() { let s1 = String::from("hello"); let s2 = s1; println!("{}", s1); }答案与解析:
- 编译结果:不能通过编译。
- 错误原因:违反了 Rust 的所有权规则。
String类型未实现Copytrait。let s2 = s1;这行代码执行的是移动操作,s1的所有权被转移给了s2,此后s1不再有效。在println!("{}", s1);中尝试使用已失效的s1会导致编译错误:borrow of moved value: \s1``。 - 修正方法:若想保留
s1的使用权,可以使用clone()进行深拷贝:let s2 = s1.clone();,或者通过引用(借用)来使用数据:let s2 = &s1;。
四、编程实践题
题目:编写一个函数calculate_average(numbers: &[f64]) -> Option<f64>,计算给定浮点数切片的平均值。如果切片为空,则返回None。
参考答案:
fn calculate_average(numbers: &[f64]) -> Option<f64> { if numbers.is_empty() { return None; // 处理空切片,返回 None } let sum: f64 = numbers.iter().sum(); // 使用迭代器的 sum 方法求和 let count = numbers.len() as f64; Some(sum / count) // 计算平均值并用 Some 包装返回 } fn main() { let data = [1.0, 2.0, 3.0, 4.0, 5.0]; match calculate_average(&data) { Some(avg) => println!("The average is: {}", avg), None => println!("Cannot calculate average for empty slice."), } let empty_data: [f64; 0] = []; match calculate_average(&empty_data) { Some(avg) => println!("Average: {}", avg), None => println!("The slice is empty."), // 预期输出此分支 } }解析:
- 函数签名:参数使用切片
&[f64]以避免获取所有权,返回Option<f64>以优雅地处理空输入。 - 边界检查:首先检查输入切片是否为空,这是使用
Option类型的典型场景。 - 迭代器使用:
numbers.iter()创建迭代器,.sum()方法对元素求和,这是 Rust 中高效且地道的集合操作方式。 - 错误处理:使用
match表达式对Option结果进行模式匹配,分别处理Some和None的情况,确保所有可能性都被覆盖。
参考来源
- 2026年Rust工程师面试题及答案.docx - 人人文库
- 2025年信息系统安全专家Rust安全编码规范专题试卷及解析.pdf-原创力文档
- Rust编程100个实例试题及答案:从基础语法到高级特性的全面解析与实践指导_Rust语法练习题带答案资源-CSDN下载
- rust编程实例试题及答案.docx - 人人文库
- 程序员Rust面试题及答案.docx-原创力文档