`?` 运算符只能在 returns `Result` 或 `Option 的异步块中使用
the `?` operator can only be used in an async block that returns `Result` or `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(());
}
谢谢!
由于正在执行转换,消息有点混乱,您可能想在错误跟踪器上报告此问题,但请注意措辞:
^ cannot use the ?
operator in an async block that returns ()
它使用的是“块”一词,而不是功能。因为这确实是一个级联错误:在幕后,一个 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<...>
,因此出现类型不兼容和您看到的错误:return 值块不连贯。
在一堆异步块错误的最后,编译器实际上显示了“源”错误:
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 `()`
并且如果您查看整个“异步块”错误,实际上每次都会注意显示错误 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`
当我在 playground 上尝试你的代码时,我遇到了很多和你一样的错误,但我也遇到了这个错误:
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(())
}
我正在学习 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(());
}
谢谢!
由于正在执行转换,消息有点混乱,您可能想在错误跟踪器上报告此问题,但请注意措辞:
^ cannot use the
?
operator in an async block that returns()
它使用的是“块”一词,而不是功能。因为这确实是一个级联错误:在幕后,一个 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<...>
,因此出现类型不兼容和您看到的错误:return 值块不连贯。
在一堆异步块错误的最后,编译器实际上显示了“源”错误:
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 `()`
并且如果您查看整个“异步块”错误,实际上每次都会注意显示错误 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`
当我在 playground 上尝试你的代码时,我遇到了很多和你一样的错误,但我也遇到了这个错误:
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(())
}