Quero armazenar algumas operações aysnc em um hashmap. Em seguida, obtenha uma lista de operações assíncronas com base na lista de strings de entrada do usuário. Pesquisando no site, encontrei esta pergunta
Como posso colocar uma função assíncrona em um mapa no Rust?
A diferença é que eu quero usar o hashmap da operação armazenada em diferentes threads do Tokio. Então eu reescrevo com once_cell + RwLock.
static MAPS: Lazy<Arc<RwLock<HashMap<&'static str, CalcFn>>>> = Lazy::new(|| {
let map = Arc::new(RwLock::new(HashMap::new()));
let mut map_lock = map.write().unwrap();
map_lock.insert(
"add",
Box::new(
move |a: i32, b: i32| -> Pin<Box<dyn Future<Output = BoxedResult<i32>>>> {
Box::pin(add(a, b))
},
) as CalcFn,
);
map_lock.insert(
"sub",
Box::new(
move |a: i32, b: i32| -> Pin<Box<dyn Future<Output = BoxedResult<i32>>>> {
Box::pin(sub(a, b))
},
) as CalcFn,
);
map.clone()
});
A inicialização lenta parece chata e ocupa muitas linhas de código porque posso ter mais de 20 operações assíncronas.
Alguém poderia gentilmente oferecer alguns comentários para escrever este exemplo de uma forma "mais limpa"?
A primeira coisa a fazer é passar o máximo possível da operação de inserção para outra função.
Você não precisa usar
clone
no final. Tudo o que você precisa fazer é soltar o cadeado antes de retornar.Você não precisa do
Arc
.Arc
pode ser usado para garantir que um valor permaneça ativo em vários threads, masstatic
já garante isso.No código que você postou, você também não precisa
RwLock
, mas pode ser necessário se você estiver modificando o mapa após a construção.Se estiver usando a versão estável mais recente do Rust, você pode usar
LazyLock
a biblioteca padrão. Funciona da mesma forma que o deonce_cell
.Geralmente, você não precisa que os erros sejam
Sync
, mas geralmente precisa que os futuros sejamSend
, para que possam ser gerados em tempos de execução multithread.Isso nos deixa com isto:
Parque infantil ferrugem