54·Unsafe Rust高级

unsafe 基础

unsafe 基础

学习目标

  1. 理解 unsafe 的作用和边界
  2. 掌握 unsafe 可以做的四件事
  3. 理解安全抽象

核心概念

unsafe 不是"关闭安全检查"

// unsafe 块允许你做编译器无法验证安全性的操作
// 但借用检查等仍然生效

unsafe {
    // 你可以:
    // 1. 解引用裸指针
    // 2. 调用 unsafe 函数
    // 3. 访问/修改可变静态变量
    // 4. 实现 unsafe trait
}

裸指针

fn main() {
    let mut num = 5;

    // 创建裸指针(安全)
    let r1 = &num as *const i32;
    let r2 = &mut num as *mut i32;

    // 解引用裸指针(必须在 unsafe 中)
    unsafe {
        println!("r1 = {}", *r1);
        *r2 = 10;
        println!("r2 = {}", *r2);
    }
}

unsafe 函数

unsafe fn dangerous() {
    println!("危险操作");
}

fn safe_wrapper() {
    // 在安全函数中封装 unsafe 操作
    unsafe {
        dangerous();
    }
}

安全抽象

fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
    let len = slice.len();
    let ptr = slice.as_mut_ptr();

    assert!(mid <= len);

    unsafe {
        (
            std::slice::from_raw_parts_mut(ptr, mid),
            std::slice::from_raw_parts_mut(ptr.add(mid), len - mid),
        )
    }
}

fn main() {
    let mut data = vec![1, 2, 3, 4, 5];
    let (left, right) = split_at_mut(&mut data, 3);
    println!("left: {:?}, right: {:?}", left, right);
}

可变静态变量

static mut COUNTER: u32 = 0;

fn add_to_count(inc: u32) {
    unsafe {
        COUNTER += inc;
    }
}

fn main() {
    add_to_count(3);
    unsafe {
        println!("COUNTER: {}", COUNTER);
    }
}

实践练习

练习 1:安全的 swap

fn my_swap<T>(a: &mut T, b: &mut T) {
    unsafe {
        let temp = std::ptr::read(a);
        std::ptr::copy_nonoverlapping(b, a, 1);
        std::ptr::write(b, temp);
    }
}

fn main() {
    let mut x = 5;
    let mut y = 10;
    my_swap(&mut x, &mut y);
    println!("x={}, y={}", x, y);
}

小结

unsafe 能做说明
解引用裸指针*const T, *mut T
调用 unsafe 函数标记为 unsafe 的函数
访问可变静态变量static mut
实现 unsafe traitunsafe trait

原则:最小化 unsafe 范围,用安全抽象封装。

练习编辑器

rust
Loading...