使用来自 tokio::runtime 的异步和盒装错误

问题描述 投票:0回答:1

我得到了这段无法编译的代码。

[dependencies] tokio = {version = "1.37.0", features = ["full"]} 

use std::error::Error;

async fn external_function() -> Result<i32, Box<dyn Error>>{
  println!("This is an external function!");
  Ok(1)
}

async fn my_function(something: i32) {
  println!("This is my function {something}");
}

#[tokio::main]
async fn main() {
  println!("Hello, world!");
  let runtime = tokio::runtime::Runtime::new().unwrap();
    runtime.spawn(async move {
      let v = external_function().await;
      if let Ok(x) = v {
          my_function(x).await;
      }
    });
}

问题是我从一个箱子中得到了一个异步函数,它返回一个

Result<T, Box<dyn Error>>
我想处理这些结果,如果是
Ok()
,请使用结果值调用我的函数。

但是我得到了这个编译器错误:

error: future cannot be sent between threads safely

鉴于我无法修改

external_function()
,实现此操作没有错误的最佳实践是什么?

一种解决方案是使

my_function()
成为非异步的,但如果我也希望它是异步的怎么办?

rust async-await rust-tokio
1个回答
0
投票

问题是我从一个箱子中得到了一个异步函数,它返回一个

Result<T, Box<dyn Error>>

通过返回

Box<dyn Error>
,该箱子给了你一个错误类型,根本不能保证线程安全。除了在单线程代码中之外,您无法传递此
Box<dyn Error>

由于该函数也是

async
,这意味着它的
Future
也必须在单线程环境中运行,例如
LocalSet
或简单地从新线程调用
Handle::block_on()

一旦你成功运行了 future,为了通过你自己的异步函数传递错误,你只能利用

Error
特征:

提供的功能
  • 使用
    Display
    特征将其转换为字符串:调用
    error.to_string()
  • 使用
    Debug
    特征将其转换为字符串:
    format!("{error:?}")
  • 如果您知道
    dyn
    背后具体的错误类型,并且该类型 is
    Send
    ,那么您可以使用
    Error::downcast()
    来获取该类型而不是
    dyn Error
    — 那么缺少
     
    + Send
    上的dyn Error
    不再重要了。
© www.soinside.com 2019 - 2024. All rights reserved.