如何通过actix-web App :: data传递多变量

问题描述

官方示例代码: 官方示例代码:

    /// use std::cell::Cell;
    /// use actix_web::{web,App,HttpResponse,Responder};
    ///
    /// struct MyData {
    ///     counter: Cell<usize>,/// }
    ///
    /// async fn index(data: web::Data<MyData>) -> impl Responder {
    ///     data.counter.set(data.counter.get() + 1);
    ///     HttpResponse::Ok()
    /// }
    ///
    /// let app = App::new()
    ///     .data(MyData{ counter: Cell::new(0) })
    ///     .service(
    ///         web::resource("/index.html").route(
    ///             web::get().to(index)));
    /// 
    pub fn data<U: 'static>(mut self,data: U) -> Self {
        self.data.push(Box::new(Data::new(data)));
        self
    }

我的问题是如何传递多变量?我从争论中得到了哪一个?

let app = App::new()
         .data(MyData{ counter: Cell::new(0) })       // <-- multi 
         .data(MyData{ counter: Cell::new(100) })     // <-- multi 
         .data(MyData{ counter: Cell::new(200) })     // <-- multi 
         .service(
             web::resource("/index.html").route(
                 web::get().to(index)));

// which MyData is this data assign to?
async fn index(data: web::Data<MyData>) -> impl Responder {
    data.counter.set(data.counter.get() + 1);
    HttpResponse::Ok()
}

此数据分配给哪个MyData? 该数据分配给哪个MyData?

解决方法

我认为web :: data按类型区分。您需要为要访问的每个数据创建一个新类型。

如果要创建相同类型的多个实例,则需要使用“新建类型”模式。参见示例:https://doc.rust-lang.org/rust-by-example/generics/new_types.html

从本质上讲,数据的“实例”及其名称是相同的。在像Java这样的语言中,您可能会采用一种将名称映射到实例的方法,并且需要将其强制转换为期望的对象类型作为值。在这种情况下,它必须严格键入类型本身。

这是一个工作示例,演示了如何对一个Counter进行定义,并具有多个实例。请注意,每个线程

有一组不同的计数器。
use std::cell::Cell;
use actix_web::{get,web,App,HttpResponse,HttpServer,Responder};

struct Counter {
    counter: Cell<usize>,}

impl Counter {
    pub fn new(value: usize) -> Counter {
        Counter { counter: Cell::new(value) }
    }

    pub fn increment(&self) -> usize {
        self.counter.set(self.counter.get() + 1);
        self.counter.get()
    }
}

struct SuccessCounter(Counter);

struct FailureCounter(Counter);

#[get("/")]
async fn index(success_counter: web::Data<SuccessCounter>,failure_counter: web::Data<FailureCounter>) -> impl Responder {
    println!("Successes: {}",success_counter.0.increment());
    println!("Failures: {}",failure_counter.0.increment());
    HttpResponse::Ok()
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .data(SuccessCounter(Counter::new(0)))
            .data(FailureCounter(Counter::new(100)))
            .service(index)
    })
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...