0

我是 rust 新手,开始尝试使用 actix_web 和 sqlx。目标是创建一个简单的开源博客引擎,但是在我实现 CLI 参数解析器和基本 SQL 连接池之后,代码不再编译。我收到以下错误:

error[E0308]: mismatched types
  --> src/main.rs:17:1
   |
17 | #[actix_web::main]
   | ^^^^^^^^^^^^^^^^^^
   | |
   | expected enum `std::result::Result`, found `()`
   | help: try using a variant of the expected enum: `Ok(#[actix_web::main])`
18 | async fn main() -> std::io::Result<()> {
   |                    ------------------- expected `std::result::Result<(), std::io::Error>` because of return type
   |
   = note:   expected enum `std::result::Result<(), std::io::Error>`
           found unit type `()`
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `rusty_read`.

To learn more, run the command again with --verbose.

该错误建议std::result::Result<(), std::io::Error>用作返回类型,但是用它替换当前返回类型时出现相同的错误:

error[E0308]: mismatched types
  --> src/main.rs:17:1
   |
17 | #[actix_web::main]
   | ^^^^^^^^^^^^^^^^^^
   | |
   | expected enum `std::result::Result`, found `()`
   | help: try using a variant of the expected enum: `Ok(#[actix_web::main])`
18 | async fn main() -> std::result::Result<(), std::io::Error> {
   |                    --------------------------------------- expected `std::result::Result<(), std::io::Error>` because of return type
   |
   = note:   expected enum `std::result::Result<(), std::io::Error>`
           found unit type `()`
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: could not compile `rusty_read`.

To learn more, run the command again with --verbose.

到目前为止,我找不到任何有同样问题的人,也找不到任何原因。

我的代码:

/货物.toml

[package]
name = "rusty_read"
version = "0.1.0"
authors = ["LeMoonStar <webmaster@unitcore.de>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-web = "3.0.0-beta.1"
rust-ini = "0.15"
sqlx = { version = "0.4.0-beta.1",  features = [ "all-databases", "any", "tls" ] }
clap = "2"

/src/main.rs

use actix_web::{get, web, App, HttpServer, Responder};
use ini::Ini;
use sqlx::pool::Pool;
use sqlx::any;


#[get("/")]
async fn index() -> impl Responder {
    format!("index")
}

#[get("/article/{id}")]
async fn article(info: web::Path<u32>) -> impl Responder {
    format!("article nr.{}", info)
}

#[actix_web::main]
async fn main() -> std::result::Result<(), std::io::Error> {
    let conf = Ini::load_from_file("conf.ini").unwrap_or(Ini::load_from_str("[Server]
    bindAddress = \"127.0.0.1:8080\"
    
    [Database]
    url = \"mysql://user:password@localhost/blog\"
    ").unwrap());
    
    let matches = clap::App::new("Rusty Read")
        .version("0.1 INDEV")
        .author("LeMoonStar <webmaster@unitcore.de>")
        .about("a blog engine written in rust")
        .subcommand(clap::SubCommand::with_name("config")
            .about("sets various configurations for the blog")
            .arg(clap::Arg::with_name("address")
                .short("a")
                .long("adress")
                .help("sets the address the http server binds on (eg. 127.0.0.1:8080)")
                .takes_value(true))
            .arg(clap::Arg::with_name("database")
                .short("d")
                .long("database")
                .help("sets the url to the database (eg. mysql://user:password@localhost/blog)")
                .takes_value(true)))
        .subcommand(clap::SubCommand::with_name("init_database")
            .about("Initializes the database which is set in the conf.ini file (or with the config command)"))

        .get_matches();

    if let Some(matches) = matches.subcommand_matches("config") {
        if matches.is_present("address") {
            conf.section(Some("Server")).unwrap()
                .insert("bindAddress", "127.0.0.1:8080");
        }
        if matches.is_present("database") {
            conf.section(Some("Database")).unwrap()
                .insert("url", "mysql://user:password@localhost/blog");
        }
    } else if let Some(matches) = matches.subcommand_matches("init_database") {
        
    } else {
        let mut section = conf.section(Some("Server")).expect("conf.ini requires a [Server] section.");
        let bind_address = section.get("bindAddress").expect("conf.ini's [Server] section requires a bindAdress.");

        section = conf.section(Some("Database")).expect("conf.ini requires a [Database] section.");
        let db_url = section.get("url").expect("conf.ini's [Database] section requires a url.");

        let pool = Pool::<any::Any>::connect(db_url).await.expect("database connection pool could not be created.");

        HttpServer::new(move || {
            App::new()
                .service(article)
                .service(index)
                .data(pool.clone())
            })
            .bind(bind_address).expect("could not bind http server")
            .run()
            .await;
    }
}

我希望有人可以帮助我解决这个问题,因为我无法继续从事该项目,而这个问题存在。

4

1 回答 1

0

Ok(())实际上正在工作..我之前尝试过复制粘贴您的所有代码,我cargo check是否遇到了与您在评论中写的相同的问题。然后我尝试清理 main 函数中的代码,然后再次逐个复制粘贴您的代码。添加后Ok(())作为主要的回报。在我完成复制粘贴之前,错误就改变了。在我的本地查看 不同错误的屏幕截图。

然后我尝试通过添加clone()如下来修复它:

..
conf.section(Some("Server")).unwrap().clone()
..
conf.section(Some("Database")).unwrap().clone()
..

然后我cargo run它。服务器工作正常!看这里的截图

于 2020-08-06T22:10:51.473 回答