How to borrow sender from a hashmap?

Hi,

this doesn't compile and says: cannot move out of a shared reference.
The send method takes ownership of self. What is the pattern to solve this problem?
I need to store the sender in a hashmap and access it later by another function or thread.

use tokio::sync::oneshot::Receiver;
use tokio::sync::oneshot::Sender;
use tokio::sync::oneshot::error::RecvError;


let mut storage: HashMap<i32, Sender<Result<i32, RecvError>>> = HashMap::new();

    // let (tx, rx: Receiver<Result<i32, RecvError>>) = oneshot::channel();

    let (tx , rx): (Sender<Result<i32, RecvError>> , Receiver<Result<i32, RecvError>>) = oneshot::channel();

    storage.insert(1, tx);

    tokio::spawn(async move {

        storage.get(&1).unwrap().send(Ok(10));

    });

    match rx.await {

        Ok(v) => println!("got = {:?}", v),
        Err(_) => println!("the sender dropped"),
    }

send takes ownership because this is a oneshot channel -- meant for only sending one value. Assuming that is in fact what you wanted to do, you could

//      vvvvvvvvvv
storage.remove(&1).unwrap().send(Ok(10));

If the hashmap is shared, you may need Arc<Mutex<HashMap>>.

Option::take is also sometimes useful for taking ownership from behind a reference, e.g. vec[index].take().unwrap().send() would work too, if you had Vec<Option<Sender>>.

1 Like

both answers are great! The reason I'm using HashMap is because I want to index them by some unique key, which I haven't implemented yet. Thank you,
cheers