如何修复“无法推断在枚举 `Result` 上声明的类型参数 E`` 的类型”?

问题描述 投票:0回答:1

我正在编写一个在线乳胶编辑器,用户可以在浏览器中编辑乳胶文档。当用户单击“编译”按钮时,我想将服务器端乳胶日志输出推送到客户端。我选择使用SSE来实现这个功能。现在我尝试像这样定义 SSE 服务器端 API:

use actix_web::{middleware::Logger, web, App, HttpRequest, HttpResponse, HttpServer};
use futures::StreamExt;

async fn sse_handler(req: HttpRequest, stream: web::Payload) -> HttpResponse {
    let mut res = HttpResponse::Ok()
        .content_type("text/event-stream")
        .streaming(Box::pin(stream.map(|chunk| {
            Ok(actix_web::web::Bytes::from(format!(
                "data: {}\n\n",
                String::from_utf8(chunk.unwrap().to_vec()).unwrap()
            )))
        })));

    if req.headers().get("cache-control").is_none() {
        res.headers_mut().insert(
            actix_web::http::header::CACHE_CONTROL,
            actix_web::http::header::HeaderValue::from_static("no-cache"),
        );
    }

    res
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .wrap(Logger::default())
            .route("/events", web::get().to(sse_handler))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

编译器显示错误:

error[E0283]: type annotations needed
   --> src/main.rs:8:13
    |
7   |         .streaming(Box::pin(stream.map(|chunk| {
    |          --------- type must be known at this point
8   |             Ok(actix_web::web::Bytes::from(format!(
    |             ^^ cannot infer type of the type parameter `E` declared on the enum `Result`
    |
    = note: cannot satisfy `_: Into<Box<(dyn std::error::Error + 'static)>>`
note: required by a bound in `HttpResponseBuilder::streaming`
   --> /Users/xiaoqiangjiang/.cargo/registry/src/mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd/actix-web-4.3.1/src/response/builder.rs:324:12
    |
324 |         E: Into<BoxError> + 'static,
    |            ^^^^^^^^^^^^^^ required by this bound in `HttpResponseBuilder::streaming`
help: consider specifying the generic arguments
    |
8   |             Ok::<actix_web::web::Bytes, E>(actix_web::web::Bytes::from(format!(
    |               ++++++++++++++++++++++++++++

我读到了这个错误,但没有弄清楚哪里出了问题。我应该怎么做才能解决这个问题并使其发挥作用?另外,这是我的 Cargo.toml:

[package]
name = "rust-learn"
version = "0.1.0"
edition = "2018"

[dependencies]
tokio = { version = "1.17.0", features = ["full"] }
serde = { version = "1.0.64", features = ["derive"] }
serde_json = "1.0.64"
actix-web = "4"
futures = "0.3"
rust server-sent-events actix-web
1个回答
2
投票

问题出在这部分,您从闭包中返回

Ok

.streaming(Box::pin(stream.map(|chunk| {
    Ok(actix_web::web::Bytes::from(format!(

如果您查看该

streaming()
方法的签名,您可以看到它对于流的错误类型是通用的:

fn streaming<S, E>(&mut self, stream: S) -> HttpResponse
    where
        S: Stream<Item = Result<Bytes, E>> + 'static,
        E: Into<BoxError> + 'static,

任何满足

Into<BoxError> + 'static
的错误都是有效的。问题是编译器没有足够的信息来知道您想要使用什么错误类型。您可以通过多种方式提供此信息。例如,如果您想使用
std::io::Error
:

.streaming(Box::pin(stream.map(|chunk| {
    std::io::Result::Ok(actix_web::web::Bytes::from(format!(

如果您想使用

Box<dyn Error>
:

use std::error::Error;
// ...
.streaming(Box::pin(stream.map(|chunk| {
    Ok::<_, Box<dyn Error>>(actix_web::web::Bytes::from(format!(

.streaming::<_, Box<dyn Error>>(Box::pin(stream.map(|chunk| {
    Ok(actix_web::web::Bytes::from(format!(
© www.soinside.com 2019 - 2024. All rights reserved.