如何解决错误“线程 'main' 在 'no current reactor' 中恐慌”?

jul*_*lia 5 future rust rust-tokio

我正在尝试连接到数据库:

extern crate tokio; // 0.2.6, features = ["full"]
extern crate tokio_postgres; // 0.5.1

use futures::executor;
use tokio_postgres::NoTls;

fn main() {
    let fut = async {
        let (client, connection) = match tokio_postgres::connect("actual stuff", NoTls).await {
            Ok((client, connection)) => (client, connection),
            Err(e) => panic!(e),
        };
        tokio::spawn(async move {
            if let Err(e) = connection.await {
                eprintln!("connection error: {}", e);
            }
        });

        let rows = match client
            .query(
                "SELECT $1 FROM planet_osm_point WHERE $1 IS NOT NULL LIMIT 100",
                &[&"name"],
            )
            .await
        {
            Ok(rows) => rows,
            Err(e) => panic!(e),
        };
        let names: &str = rows[0].get("name");
        println!("{:?}", names);
    };
    executor::block_on(fut);
    println!("Hello, world!");
}
Run Code Online (Sandbox Code Playgroud)

它编译了,但是当我运行它时,我收到了错误消息

extern crate tokio; // 0.2.6, features = ["full"]
extern crate tokio_postgres; // 0.5.1

use futures::executor;
use tokio_postgres::NoTls;

fn main() {
    let fut = async {
        let (client, connection) = match tokio_postgres::connect("actual stuff", NoTls).await {
            Ok((client, connection)) => (client, connection),
            Err(e) => panic!(e),
        };
        tokio::spawn(async move {
            if let Err(e) = connection.await {
                eprintln!("connection error: {}", e);
            }
        });

        let rows = match client
            .query(
                "SELECT $1 FROM planet_osm_point WHERE $1 IS NOT NULL LIMIT 100",
                &[&"name"],
            )
            .await
        {
            Ok(rows) => rows,
            Err(e) => panic!(e),
        };
        let names: &str = rows[0].get("name");
        println!("{:?}", names);
    };
    executor::block_on(fut);
    println!("Hello, world!");
}
Run Code Online (Sandbox Code Playgroud)

She*_*ter 1

当使用许多(但不是全部)Tokio 功能时,您必须使用 Tokio 反应器。在您的代码中,您尝试使用 futures crate ( executor::block_on) 提供的通用执行器。使用 Tokio 执行器和反应器通常是通过使用宏来完成的#[tokio::main]

#[tokio::main]
async fn main() {
    let (client, connection) = match tokio_postgres::connect("actual stuff", NoTls).await {
        Ok((client, connection)) => (client, connection),
        Err(e) => panic!(e),
    };
    tokio::spawn(async move {
        if let Err(e) = connection.await {
            eprintln!("connection error: {}", e);
        }
    });

    let rows = match client
        .query(
            "SELECT $1 FROM planet_osm_point WHERE $1 IS NOT NULL LIMIT 100",
            &[&"name"],
        )
        .await
    {
        Ok(rows) => rows,
        Err(e) => panic!(e),
    };
    let names: &str = rows[0].get("name");
    println!("{:?}", names);
}
Run Code Online (Sandbox Code Playgroud)

tokio_postgres 文档中的第一个示例甚至向您展示了如何执行此操作:

#[tokio::main] // By default, tokio_postgres uses the tokio crate as its runtime.
async fn main() -> Result<(), Error> {
Run Code Online (Sandbox Code Playgroud)

发生这种情况的原因之一是因为您正在使用tokio::spawn此记录的

如果从 Tokio 运行时外部调用,则会发生恐慌。

也可以看看:


这不会打印你想要的内容:

Err(e) => panic!(e),
Run Code Online (Sandbox Code Playgroud)

你要

Err(e) => panic!("{}", e),
Run Code Online (Sandbox Code Playgroud)