appdata - 如何通过 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
}
推荐阅读
- react-native - React - 本机开发服务器返回响应错误代码:500
- javascript - ctx 画布图像从底部减小宽度
- java - 当数字 6.02E23 舍入时,java 究竟在做什么?
- xml - 通过 XPath 提取 html 标记内的文本
- c++ - 如何在给定范围内打印出周长和直角三角形的数量?
- android - 如何使用 Django for Android 执行注册和登录 Api
- python - 学习正弦函数似乎在 ANN (Keras) 中采用了过多的参数
- python - OpenCV filter2d 给出不正确的结果
- android - 如何使用数组修复for循环中的应用程序崩溃
- sqlite - 截断使用 SDL RWops 打开的文件