如何通过 actix-web App::data() 传递多变量
How can I pass multi variable by 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 这样的语言中,您可能会采用一种方法,其中存在名称到实例的映射,并且您需要转换为您期望的对象类型作为值。在这种情况下,它严格以类型本身为键。
这是一个工作示例,它演示了如何使用一个计数器定义及其多个实例。请注意,每个线程有一组不同的计数器 :
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
}
官方示例代码: 官方示例代码:
/// 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 这样的语言中,您可能会采用一种方法,其中存在名称到实例的映射,并且您需要转换为您期望的对象类型作为值。在这种情况下,它严格以类型本身为键。
这是一个工作示例,它演示了如何使用一个计数器定义及其多个实例。请注意,每个线程有一组不同的计数器 :
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
}