Rust unsafe代码:何时使用与安全抽象
3 阅读
预计 3 分钟
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不是"不安全",而是"编译器无法验证的安全性由程序员保证"。
0 条评论 欢迎参与讨论