如何为Rust改变Rocket框架中的状态?



我正在尝试使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中的那些。

相关内容

  • 没有找到相关文章

最新更新