的' ?'操作符只能用于返回' Result '或' Option '的异步块



我正在学习rust,并试图通过发送一些POST数据来抓取随机站点,我得到了一堆错误,如:

error[E0277]: the `?` operator can only be used in an async block that returns `Result` or `Option` (or another type that implements `FromResidual`)
37  | |     let text = res.text().await?;
| |                                ^ cannot use the `?` operator in an async block that returns `()`

代码如下。我已经通过文档多次,但我返回一个结果<>所以我不知道怎么了。

use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Hello, world!");
use reqwest::{cookie::Jar, Url};
use reqwest::header;
let mut headers = header::HeaderMap::new();
headers.insert("User-Agent", header::HeaderValue::from_static("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"));
headers.insert("Content-Type", header::HeaderValue::from_static("application/json"));

let cookie = "cookies";
let jar = Jar::default();
let cookie_url = "https://url.com/".parse::<Url>()?;
jar.add_cookie_str(cookie, &cookie_url);
let body = String::from("post body"); 
let client = reqwest::Client::builder()
.default_headers(headers)
.cookie_store(true)
.cookie_provider(Arc::new(jar))
.build()?;
let path = "https://long_url.com".parse::<Url>()?;
let res = client
.post(path)
.body(body)
.send()
.await?;
let text = res.text().await?;
println!("{}", text);
Ok(());
}

谢谢!

由于正在执行的转换,该消息有点令人困惑,您可能希望在错误跟踪器上报告此消息,但请注意措辞:

^不能在异步块中使用?操作符返回()

它使用了"block"这个词,而不是"function"。因为这实际上是一个级联错误:在幕后,一个async函数被转换成一个状态机,其中每个await是一个"屈服点";在代码块之间,所以

let res = client
.post(path)
.body(body)
.send()
.await?;
let text = res.text().await?;
println!("{}", text);
Ok(());

可以被理解为(这不是真正的变换,如果你想要一个真正的解构Jon Gjengset有一个关于这个主题的广泛视频)

let future = async {
client.post(path).body(body).send()
};
yield future;
let future = async {
let res = future.value()?;
res.text()
};
yield future;
let future = async {
let text = future.value()?;
println!("{}", text);
Ok(());
};
return future;

注意最后一个块的最后一个表达式,这就是问题发生的地方:它是Ok(());

后面的分号将"抑制";表达式的正常值和结果是(),而不是Result<...>,因此类型不兼容,您看到的错误是:块的返回值不一致。

在异步块错误堆的末尾,编译器实际上显示了&;source&;错误:

error[E0308]: mismatched types
--> src/main.rs:6:20
|
6 | async fn main() -> Result<(), Box<dyn std::error::Error>> {
|          ----      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `()`
|          |
|          implicitly returns `()` as its body has no tail or `return` expression
|
= note:   expected enum `Result<(), Box<(dyn std::error::Error + 'static)>>`
found unit type `()`

如果你看整个"async block"错误时,每次:

时都会显示错误的Ok(());
error[E0277]: the `?` operator can only be used in an async block that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> src/lib.rs:19:55
|
6   |   async fn main() -> Result<(), Box<dyn std::error::Error>> {
|  ___________________________________________________________-
7   | |     println!("Hello, world!");
8   | |
9   | |     use reqwest::{cookie::Jar, Url};
...   |
19  | |     let cookie_url = "https://url.com/".parse::<Url>()?;
| |                                                       ^ cannot use the `?` operator in an async block that returns `()`
...   |
41  | |     Ok(());
42  | | }
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Result<Infallible, url::parser::ParseError>>` is not implemented for `()`
note: required by `from_residual`

当我在操场上尝试你的代码时,我得到了很多像你一样的错误,但我也得到了这个错误:

error[E0308]: mismatched types
--> src/main.rs:5:20
|
5 | async fn main() -> Result<(), Box<dyn std::error::Error>> {
|          ----      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `()`
|          |
|          implicitly returns `()` as its body has no tail or `return` expression
|
= note:   expected enum `Result<(), Box<(dyn std::error::Error + 'static)>>`
found unit type `()`

这是由main函数末尾的额外分号引起的。删除分号将修复所有错误:

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Hello, world!");
use reqwest::{cookie::Jar, Url};
use reqwest::header;
let mut headers = header::HeaderMap::new();
headers.insert("User-Agent", header::HeaderValue::from_static("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"));
headers.insert("Content-Type", header::HeaderValue::from_static("application/json"));

let cookie = "cookies";
let jar = Jar::default();
let cookie_url = "https://url.com/".parse::<Url>()?;
jar.add_cookie_str(cookie, &cookie_url);
let body = String::from("post body"); 
let client = reqwest::Client::builder()
.default_headers(headers)
.cookie_store(true)
.cookie_provider(Arc::new(jar))
.build()?;
let path = "https://long_url.com".parse::<Url>()?;
let res = client
.post(path)
.body(body)
.send()
.await?;
let text = res.text().await?;
println!("{}", text);
Ok(())
}

游乐场

相关内容

  • 没有找到相关文章

最新更新