unsafe代码是Rust的逃生舱口。本文讲解何时该用unsafe,以及如何用unsafe构建安全抽象。 ## unsafe的五种能力 1. 解引用裸指针 2. 调用unsafe函数 3. 访问可变静态变量 4. 实现unsafe trait 5. 访问union字段 ## 裸指针 ```rust let mut num = 5; let r1 = &num as *const i32; let r2 = &mut num as *mut i32; unsafe { println!("r1 = {}", *r1); *r2 = 10; println!("r2 = {}", *r2); } ``` ## unsafe函数 ```rust unsafe fn dangerous() { // 危险操作 } unsafe { dangerous(); } ``` ## 安全抽象 ```rust use std::slice; fn split_at_mut(values: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) { let len = values.len(); let ptr = values.as_mut_ptr(); assert!(mid <= len); unsafe { ( slice::from_raw_parts_mut(ptr, mid), slice::from_raw_parts_mut(ptr.add(mid), len - mid), ) } } ``` ## FFI(外部函数接口) ```rust extern "C" { fn abs(input: i32) -> i32; } fn main() { unsafe { println!("Absolute value: {}", abs(-3)); } } ``` ## 原则 - unsafe块应尽可能小 - 每个unsafe块都应有安全注释说明为何安全 - 优先使用安全API,只在性能或FFI必要时使用unsafe - 用unsafe构建的API对外必须是安全的 unsafe不是"不安全",而是"编译器无法验证的安全性由程序员保证"。