在返回 `()` 的函数中不能使用 `?` 运算符。

12

我对 Rust 还非常陌生,我想写一个脚本来爬取一个页面,并将其中所有链接和它们的标题提取出来。但是,我甚至无法完成 GET 请求。:(

我很新手rust,我想编写一个脚本来抓取一个页面并提取其中每个带有标题的链接,但是我甚至不能发起GET请求。:(

fn main() {
    println!("Started!");
    let body = reqwest::get("https://news.ycombinator.com")
    .await?
    .text()
    .await?;

    println!("body = {:?}", body);
}

很明显我没有返回任何东西,但是我对语法感到困惑。有人能解释一下这个“?”运算符并帮我修复这个问题吗?


1
https://doc.rust-lang.org/std/result/#the-question-mark-operator- - Sergio Tulentsev
https://rust-lang.github.io/async-book/07_workarounds/03_err_in_async_blocks.html - Sergio Tulentsev
1个回答

15

问号运算符只能在返回 std::Result 的函数内使用。简单来说,您可以将 x? 理解为

match x {
    Err(e) => return Err(e),
    Ok(y) => y,
}

(请参阅此处的文档here)

如果您不希望出现错误,那么当await产生错误结果时,您希望发生什么? 如果您不期望错误发生,则告诉Rust在发生错误时崩溃(即崩溃)应该是安全的。 这就是Result::unwrap的作用:

fn main() {
    println!("Started!");
    let body = reqwest::get("https://news.ycombinator.com")
        .await
        .unwrap()
        .text()
        .await
        .unwrap();

    println!("body = {:?}", body);
}

更有可能的是,你应该有一些良好定义的行为来负责处理错误结果。这可以尝试恢复(即尝试其他方法),或者如果你在顶层main函数中,则记录错误消息并以非零代码退出。简单的方法是使用match语句。

从这个角度来看,?运算符的意图变得清晰:它是一种说法的方式,即“处理此错误不是我的责任–而是调用我的代码的责任。”这里重要的是仍然有某人需要负责决定如何处理错误。


1
只是一个小问题。请在生产代码中尽量避免使用unwrap()。 - captain-yossarian from Ukraine
我该如何在不使用unwrap的情况下完成它? - shredding
使用 match!我已经编辑了答案以涵盖此选项。 - user31601

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接