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

无依赖Rust异步block_on极简实现:如何移除unsafe关键字?

如何在无依赖前提下移除阻塞执行器中的unsafe关键字?

我实现了一个尽可能精简的阻塞执行器,但代码里用到了unsafe关键字,没办法移除。以下是仅用于调试、无外部依赖的代码:

use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};

// 创建空操作waker
fn dummy_raw_waker() -> RawWaker {
    fn no_op_clone(_: *const ()) -> RawWaker {
        dummy_raw_waker()
    }

    fn no_op(_: *const ()) {}

    RawWaker::new(
        core::ptr::null(),
        &RawWakerVTable::new(no_op_clone, no_op, no_op, no_op),
    )
}

// 仅用于调试、无依赖的阻塞函数
pub fn debug_only_unsafe_block_on<F: Future>(mut future: F) -> F::Output {
    let waker = unsafe { Waker::from_raw(dummy_raw_waker()) };
    let mut context = Context::from_waker(&waker);

    // 在栈上Pin future
    let mut future = unsafe { Pin::new_unchecked(&mut future) };

    loop {
        match future.as_mut().poll(&mut context) {
            Poll::Ready(val) => return val,
            Poll::Pending => {
                // 在真实系统中可能需要切换到其他任务,但本场景仅持续轮询
            }
        }
    }
}

可以在不引入额外依赖的前提下完全移除unsafe关键字,只需对两处核心代码做修改:

  1. 替换手动实现的空Waker
    Rust标准库从1.51版本起提供了Waker::noop()方法,直接返回一个空操作的waker,完全替代你手动实现的dummy_raw_waker和unsafe { Waker::from_raw(...) }调用,无需任何unsafe。

  2. 安全Pin Future
    原代码用Pin::new_unchecked在栈上Pin非Unpin的Future是不安全的,我们可以将Future放到堆上,通过Box::pin()安全创建Pin<Box<F>>——堆分配的Future被Pin后内存地址固定,不会被移动,完全满足Pin的安全要求。

修改后的完整代码:

use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll, Waker};

// 仅用于调试、无依赖的阻塞函数
pub fn debug_only_block_on<F: Future>(future: F) -> F::Output {
    let waker = Waker::noop();
    let mut context = Context::from_waker(&waker);

    // 将Future放到堆上并安全Pin
    let mut future = Box::pin(future);

    loop {
        match future.as_mut().poll(&mut context) {
            Poll::Ready(val) => return val,
            Poll::Pending => {
                // 调试场景下持续轮询,无其他任务调度
            }
        }
    }
}

说明

  • Waker::noop()的行为和你手动实现的空waker完全一致:所有waker操作都是空实现,不会触发任何唤醒逻辑。
  • Box::pin()是标准库提供的安全API,无需手动保证Pin的安全条件,适配所有Future类型。
  • 这段代码完全移除了unsafe,仅依赖core库,和原代码的调试场景完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 00:20:03