We all know that Arc is a thread-safe reference-counting pointer. ‘Arc’ stands for ‘Atomically Reference Counted’.
But have you ever think about what will happen if Arc is only applied in one thread. Can it be mutable? Does the Mutex still needed?
Suppose got a scene like:
// try manipulate the val in Arc without the aid of Mutex
use std::sync::{Arc, Mutex};
fn main() {
use std::thread;
let mut five = Arc::new("okk".to_string());
five.push_str("!");
for _ in 0..10 {
let tfive = five.clone();
thread::spawn(move || {
println!("{tfive:?}");
});
}
}
# Error
--> src/main.rs:6:9
|
6 | let mut five = Arc::new("okk".to_string());
| ----^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
error[E0596]: cannot borrow data in an `Arc` as mutable
--> src/main.rs:7:5
|
7 | five.push_str("!");
| ^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
|
= help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Arc<String>`
For more information about this error, try `rustc --explain E0596`.
According to the hint from compiler, the key is trait DerefMut
Yyyyyyyyyyes, Arc only implements Deref
rather than DerefMut
. So only the method that called by &self
can be adjusted. That’s why Mutex has to be wrapped outside the target value to complete the chain-style dereference: Arc
-Deref→
Mutex
-DerefMut→
value