作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在将来自外部服务的数据存储在本地缓存中,我想创建一个端点来返回当前缓存中的数据。
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
use rocket::{Route, State};
use rocket_contrib::json::Json;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct Post {
pub title: String,
pub body: String,
}
impl Post {
pub fn new(title: String, body: String) -> Post {
Post { title, body }
}
}
pub struct Cache {
pub posts: Vec<Post>,
}
impl Cache {
pub fn new() -> Cache {
let mut posts = vec![
Post::new(String::from("Article1"), String::from("Blah")),
Post::new(String::from("Article2"), String::from("Blah")),
Post::new(String::from("Article3"), String::from("Blah")),
Post::new(String::from("Article4"), String::from("Blah")),
Post::new(String::from("Article5"), String::from("Blah")),
];
Cache { posts }
}
}
#[derive(Responder)]
pub enum IndexResponder {
#[response(status = 200)]
Found(Json<Vec<Post>>),
#[response(status = 404)]
NotFound(String),
}
#[get("/")]
pub fn index(cache: State<Cache>) -> IndexResponder {
return IndexResponder::Found(Json(cache.posts));
}
fn main() {
rocket::ignite()
.mount("/", routes![index])
.manage(Cache::new())
.launch();
}
编译器提示:
error[E0507]: cannot move out of dereference of `rocket::State<'_, Cache>`
--> src/main.rs:50:39
|
50 | return IndexResponder::Found(Json(cache.posts));
| ^^^^^^^^^^^ move occurs because value has type `std::vec::Vec<Post>`, which does not implement the `Copy` trait
( cargo build --verbose
output )
我的 Cargo.toml 文件:
[package]
name = "debug-project"
version = "0.1.0"
authors = ["Varkal <mail@example.com>"]
edition = "2018"
[dependencies]
rocket = "0.4.0"
rocket_contrib = "0.4.0"
serde = { version = "1.0.90", features = ["derive"] }
serde_json = "1.0.39"
最佳答案
您的端点不拥有该状态,因此它无法返回拥有的 Vec<Post>
.从概念上讲,这是有道理的,因为如果您确实取得了它的所有权,那么下次调用端点时会出现什么值?
您可以做的最简单的事情就是克隆数据:
#[get("/")]
pub fn index(cache: State<Cache>) -> IndexResponder {
IndexResponder::Found(Json(cache.posts.clone()))
}
这将要求您实现 Clone
对于 Post
,或者改变你的状态来保存类似 Arc
的东西.
一个稍微更高效的解决方案是返回一个引用状态的切片。这不需要克隆,但需要使用 State::inner
方法:
#[derive(Responder)]
pub enum IndexResponder<'a> {
#[response(status = 200)]
Found(Json<&'a [Post]>),
#[response(status = 404)]
NotFound(String),
}
#[get("/")]
pub fn index<'a>(cache: State<'a, Cache>) -> IndexResponder<'a> {
IndexResponder::Found(Json(&cache.inner().posts))
}
另见:
关于rust - 如何从 Rocket 端点返回状态值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56636643/
我是一名优秀的程序员,十分优秀!