简体   繁体   English

Hashmap 值不会在连续插入时更新 [Rust]

[英]Hashmap value not updating on consecutive inserts [Rust]

I have a struct that contains various Routers.我有一个包含各种路由器的结构。 Mostly hashmaps.主要是哈希图。 But for this specific hashmap, the values are not updating after insertion.但是对于这个特定的 hashmap,插入后值不会更新。 There is no delete function.没有删除 function。 Just an insert function(shown below).只是一个插入功能(如下所示)。

This is the main struct这是主要结构

pub struct Router {
....
    web_socket_routes: Arc<RwLock<HashMap<String, HashMap<String, (PyFunction, u8)>>>>,
}

This is a getter这是一个吸气剂

    #[inline]
    pub fn get_web_socket_map(
        &self,
    ) -> &Arc<RwLock<HashMap<String, HashMap<String, (PyFunction, u8)>>>> {
        &self.web_socket_routes
    }

This is the insert method这是插入方法

    pub fn add_websocket_route(
        &mut self,
        route: &str,
        connect_route: (Py<PyAny>, bool, u8),
        close_route: (Py<PyAny>, bool, u8),
        message_route: (Py<PyAny>, bool, u8),
    ) {
        let table = self.get_web_socket_map();
        let (connect_route_function, connect_route_is_async, connect_route_params) = connect_route;
        let (close_route_function, close_route_is_async, close_route_params) = close_route;
        let (message_route_function, message_route_is_async, message_route_params) = message_route;

        let insert_in_router =
            |handler: Py<PyAny>, is_async: bool, number_of_params: u8, socket_type: &str| {
                let function = if is_async {
                    PyFunction::CoRoutine(handler)
                } else {
                    PyFunction::SyncFunction(handler)
                };

                let mut route_map = HashMap::new();
                route_map.insert(socket_type.to_string(), (function, number_of_params));

                println!("socket type is {:?} {:?}", table, route);
                table.write().unwrap().insert(route.to_string(), route_map);
            };

        insert_in_router(
            connect_route_function,
            connect_route_is_async,
            connect_route_params,
            "connect",
        );

        insert_in_router(
            close_route_function,
            close_route_is_async,
            close_route_params,
            "close",
        );

        insert_in_router(
            message_route_function,
            message_route_is_async,
            message_route_params,
            "message",
        );
    }

After all the 3 insert_in_router calls, web_socket_routes only contains the insertion of the last insert_in_router call?在所有 3 个insert_in_router调用之后, web_socket_routes只包含最后一个insert_in_router调用的插入?

I have tried changing the Arc<RwLock< for a generic DashMap but I am still facing the same issues.我尝试将Arc<RwLock<更改为通用DashMap ,但我仍然面临同样的问题。

Why is this happening?为什么会这样?

Your closure unconditionally creates a new inner HashMap each time, which it uses as value in the outer hashmap.您的闭包每次都会无条件地创建一个新的内部HashMap ,并将其用作外部 hashmap 中的值。 However, it puts it into the outer hashmap under the same key ( route.to_string() ) all three times, which results in each insert overwriting the previous one(s).但是,它将它放入外部 hashmap 中的同一键 ( route.to_string() ) 下所有 3 次,这导致每次插入都会覆盖前一个。

You need to implement a logic that will create a new inner hashmap only if the key is missing.您需要实现一个逻辑,仅当缺少密钥时才会创建新的内部 hashmap。 Then it should insert the value into the inner hashmap, either the freshly created one, or the one looked up.然后它应该将值插入到内部 hashmap 中,要么是新创建的,要么是查找的。 In Rust this is done using the entry API:在 Rust 中,这是使用条目 API 完成的:

table
    .write()
    .unwrap()
    .entry(route.to_string())
    .or_default()
    .insert(socket_type.to_string(), (function, number_of_params))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM