我正在尝试使State
类型工作,这应该代表服务器的状态。不幸的是,我收到这个错误:
error[E0596]: cannot borrow data in dereference of `rocket::State<FunnyDatabase>` as mutable
--> srcroutes.rs:9:25
|
9 | if let Some(room) = rooms.0.iter_mut().find(|room| room.name == room_id) {
| ^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
|
= help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `rocket::State<FunnyDatabase>`
对于片段:
#[post("/join_room/<room_id>/<player_name>")]
pub fn join_room(room_id: String, player_name: String, rooms: &State<FunnyDatabase>) -> (Status, (ContentType, String)) {
if let Some(room) = rooms.0.iter_mut().find(|room| room.name == room_id) {
room.players.push_back(Player{ name: player_name.clone(), card: "UNKNOWN".to_string() });
}
...
其中FunnyDatabase
是数据库的模拟:
pub struct FunnyDatabase(pub LinkedList<Room>);
状态应该被管理:
rocket::build()
.manage(FunnyDatabase(LinkedList::<Room>::new()))
...
Room是一个简单的结构体:
pub struct Room {
pub name: String,
pub players: LinkedList<Player>
}
我如何解决这个问题,我如何理解如何处理这类问题?
我使用的是Rocket版本"0.5.0-rc.3"。和Rust版本1.68.2
我试过强迫类型是可变的,但不幸的是它不起作用。我搜索了几个小时关于在这个框架中改变状态的信息,但没有找到任何相关信息。文档只提到了检索状态,但没有提到更改状态。搜索引擎不提供任何结果。这个结构是有效的遗留代码吗?我是否应该使用其他东西来实现存储Room
集合的目标,其中包含Player
集合?
感谢您的指导!
您需要使用具有内部可变性的类型。例如:Mutex
.
pub struct Room {
pub name: String,
pub players: Mutex<LinkedList<Player>>
}
然后你可以通过锁定互斥锁来修改列表。
if let Some(room) = rooms.0.iter().find(|room| room.name == room_id) {
room.players.lock().unwrap().push_back(Player {
name: player_name.clone(),
card: "UNKNOWN".to_string()
});
}
还有RwLock
,以及许多标准库之外的内部可变性原语,例如parking_lot
中的那些。