1. The Problem
Consider the following function where self.cache is of type HashMap<String, BlockChain>:
async fn get_index(&self) -> HttpResponse { let blockchain = self.cache.lock().unwrap().get("blockchain").unwrap(); let first_block = blockchain[0].clone(); let block_json = serde_json::to_string(&first_block).unwrap(); debug!("block_json {:?}", block_json); HttpResponse::Ok().json(block_json) }
Problem:
The reason is that:
self.cache.lock()is aMutexGuardobject with life time'aself.cache.lock().gethas signature:impl<K, V> HashMap<K, V> { pub fn get<'a, Q>(&'a self, k: &Q) -> Option<&'a V>self.cache.lock().get("key").unwrap()is a&BlockChainobject, i.e., a pointer- Pointer can never be moved, it will be copied whenever we assign it to another variable. Now 
blockchain = self.cache.lock().get("key").unwrap()is a copy of a pointer self.cache.lock()is a temporary value, now it gets dropped at the end of the statement after;self.cache.lock().getis now borrowing a dropped value, hence crashed
Remark. By dropped we mean that the value has executed its drop method implemented for the Drop trait. Most of the time it is a cleanup process for freeing the memory, but it is not always true.
2. Solution
We simply move the temporary data to a local variable which has longer life span (so that the .get() makes sense):
async fn get_index(&self) -> HttpResponse { let unlocked_cache = self.cache.lock().unwrap(); let blockchain = unlocked_cache.get("blockchain").unwrap(); let first_block = blockchain[0].clone(); let block_json = serde_json::to_string(&first_block).unwrap(); debug!("block_json {:?}", block_json); HttpResponse::Ok().json(block_json) }














