Modifying a global String in a Mutex


How can I modify the global string here:

lazy_static! {
    static ref MY_STRING: Mutex<String> = Mutex::new(String::new());

// in a function
*MY_STRING.get_mut().unwrap() = some_string;

I have this error:

error[E0596]: cannot borrow data in a dereference of `MY_STRING` as mutable                    
  --> src\
88 |                 *MY_STRING.get_mut().unwrap() = refresh_token;
   |                  ^^^^^^^^^^^^^ cannot borrow as mutable
   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `MY_STRING`

To modify things under mutex, you should lock it first. This is where the Rust really shines, you can't modify it without retain its lock. In safe Rust, data race is not possible even by intension.

*MY_STRING.lock().unwrap() = reference_token;

You may wonder why .get_mut() doesn't work here. For this kind of questions always check the function signature first.

pub fn get_mut(&mut self) -> LockResult<&mut T>

It takes &mut self which is read as "unique reference to the self". Obviously you cannot take an unique reference from the global variable, as everyone can freely reference it.

edit: fix the double star

1 Like


I was confused by the doc I think:

it says: "Since this call borrows the Mutex mutably, no actual locking needs to take place -- the mutable borrow statically guarantees no locks exist." and I misunderstood that.

The double * didn't work for me, a single one did though. :smiley:

I believe Mutex::get_mut() is meant for cases where nothing else is borrowing the Mutex and you have unique ownership. In those situations the borrow checker has statically proven that nothing else can try to take the lock, so you can skip the entire locking process and access the underlying data directly.

I don't think I've ever needed to use it.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.