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

使用Tokio实现Promise系统时遇Fn闭包所有权错误求助

解决Tokio oneshot Sender在Fn闭包中移动的错误

错误原因

  • tokio::sync::oneshot::Sender的send方法会获取自身所有权(方法签名为pub fn send(mut self, t: T) -> Result<(), T>),调用一次后tx就会被移动,无法再次使用。
  • 你的task_prom函数要求回调实现Fn(i32) trait,Fn的核心要求是闭包可以被多次调用。但你的闭包在第一次执行时就会把tx移走,这违反了Fn的约束——Rust编译器必须保证闭包能重复调用,因此不允许在Fn闭包中移动捕获的非Copy类型变量。

解决方案

方案1:将回调类型改为FnOnce(推荐)

由于你的逻辑中callback(x)只会被调用一次(仅当x == 10时执行),完全可以把task_prom的回调参数类型从Fn改为FnOnce。FnOnce trait允许闭包消耗捕获的变量(即移动tx),正好匹配你的场景:

use std::time::Duration;

use tokio::sync::oneshot::{channel};
use tokio::time::sleep;

// 将Fn改为FnOnce
async fn task_prom(callback: impl FnOnce(i32)) {
    for x in 1..=10 {
        if x == 10 {
            callback(x);
        }
        sleep(Duration::from_secs(1)).await;
    }
}

async fn handler() -> i32 {
    let (tx, rx) = channel::<i32>();
    task_prom(move |x| tx.send(x).unwrap()).await;
    rx.await.unwrap()
}

#[tokio::main]
async fn main() {
    let res = handler().await;
    println!("{}", res);
}

方案2:用Arc<Mutex>包装Sender(适用于可能多次调用回调的场景)

如果你的业务逻辑需要回调被多次调用(尽管当前场景不需要),可以用Arc<Mutex>包装Sender,让闭包可以安全地多次访问Sender:

use std::sync::Arc;
use std::time::Duration;

use tokio::sync::{oneshot::{channel}, Mutex};
use tokio::time::sleep;

async fn task_prom(callback: impl Fn(i32)) {
    for x in 1..=10 {
        if x == 10 {
            callback(x);
        }
        sleep(Duration::from_secs(1)).await;
    }
}

async fn handler() -> i32 {
    let (tx, rx) = channel::<i32>();
    let tx = Arc::new(Mutex::new(tx));
    task_prom(move |x| {
        // 克隆Arc,保证闭包可以被多次调用
        let tx_clone = tx.clone();
        tokio::spawn(async move {
            let mut tx = tx_clone.lock().await;
            let _ = tx.send(x); // oneshot第二次send会返回Err,忽略即可
        });
    }).await;
    rx.await.unwrap()
}

#[tokio::main]
async fn main() {
    let res = handler().await;
    println!("{}", res);
}

注意:oneshot通道的Sender只能成功发送一次数据,后续调用send会返回Err,因此方案1更贴合你当前的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 04:00:37