You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无需unsafe代码即可使用原始指针的实用场景探究

哈哈,这个问题问得太到位了!很多人一提到原始指针(raw pointer)就直接联想到unsafe,但其实Rust里还真有不少不用写一行unsafe就能合法使用它们的实用场景,我给你捋几个最常见的:

无需unsafe的原始指针实用场景

1. 作为类型标记/逻辑关联的占位符

有时候我们需要在自定义类型里标记“这个类型逻辑上关联了某类资源的指针”,但又不需要实际持有或操作资源内容。这时候原始指针可以用来当一个轻量的标记,完全不用unsafe:

// 用空类型指针标记这是一个文件资源句柄
struct FileHandle(*const ());

impl FileHandle {
    // 安全创建句柄,用空指针作为初始标记
    fn new() -> Self {
        FileHandle(std::ptr::null())
    }
}

这里的*const ()只是个类型标记,用来区分不同的资源句柄类型,全程不需要触碰unsafe。

2. 空指针的判断与传递

Rust提供了std::ptr::null()、std::ptr::null_mut()这些安全函数,返回的空指针可以在安全代码里自由使用:

  • 用来表示“无资源”的状态
  • 作为参数传递给需要空指针的API(调用C API本身是unsafe,但准备空指针的过程是安全的)
  • 用is_null()方法安全判断指针是否为空

示例代码:

fn get_optional_resource() -> *const u8 {
    // 模拟根据业务逻辑返回空指针或占位指针
    if resource_unavailable() {
        std::ptr::null()
    } else {
        // 这里的 dangling() 返回一个不指向有效内存的指针,但创建它是安全的
        unsafe { std::ptr::NonNull::dangling().as_ptr() }
    }
}

// 安全判断指针是否为空
fn has_resource(ptr: *const u8) -> bool {
    !ptr.is_null()
}

3. 安全的指针类型转换

只要不涉及解引用,原始指针的类型转换是完全安全的。比如:

  • 可变指针转不可变指针:*mut T → *const T
  • 任意类型指针转空类型指针:*const T → *const ()
  • 指针的宽化转换(比如*const u8 → *const i8)

示例:

let mut num = 42;
let mut_ptr: *mut i32 = &mut num;

// 安全转换:可变转不可变
const_ptr: *const i32 = mut_ptr;
// 安全转换:转成通用空类型指针
unit_ptr: *const () = const_ptr as *const ();

这种转换在需要统一处理不同类型的资源指针时特别有用。

4. 作为哈希集合的键或存入容器

原始指针已经实现了Hash和Eq trait,所以可以安全地放进HashSet或者作为HashMap的键,用来追踪内存地址的唯一性,全程不用unsafe:

use std::collections::HashSet;

fn track_active_resources() {
    let mut active = HashSet::new();
    
    let resource_a = 100;
    let ptr_a = &resource_a as *const i32;
    active.insert(ptr_a);
    
    // 安全判断指针是否已被追踪
    assert!(active.contains(&ptr_a));
}

这里只是比较指针的地址值,完全不涉及内存访问,所以是安全的。

5. 在常量中定义原始指针

Rust允许在安全的常量上下文中定义原始指针,比如指向静态变量的指针,或者空指针:

// 安全定义空指针常量
const NULL_U32_PTR: *const u32 = std::ptr::null();

// 指向静态变量的指针,编译时就能确定地址,安全定义
static GLOBAL_CONFIG: i32 = 99;
const CONFIG_PTR: *const i32 = &GLOBAL_CONFIG;
核心逻辑总结

这些场景的共同点是:只操作指针本身的地址或类型,绝不进行解引用、读写指针指向的内存这类会触发内存不安全的操作。Rust的安全机制允许我们在安全代码里持有和操作原始指针,只要不越界触碰那些需要unsafe才能做的事。

内容的提问来源于stack exchange,提问作者at54321

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:02:44