LINUX.ORG.RU

История изменений

Исправление hippi90, (текущая версия) :

Ок, давай с примерами, а то мы кажется о разном говорим

let mut obj = Arc::new(String::new()); // создаем объект, пусть будет Arc, объявляем его как мутабельный

let a = &obj; // берем обычную ссылку, всё ок
let b = &obj; // берем еще одну обычную ссылку, всё еще ок
let с = &mut obj; // пытаемся взять мутабельную ссылку, получаем ошибку cannot borrow `obj` as mutable because it is also borrowed as immutable

Попробуем в обратном порядке

let mut obj = Arc::new(String::new()); // создаем объект, пусть будет Arc, объявляем его как мутабельный

let a = &mut obj; // берем мутабельную ссылку, всё ок
let b = &obj; // пытаемся взять обычную ссылку, получаем ошибку cannot borrow `obj` as immutable because it is also borrowed as mutable

Давай пример посложнее

let mut obj = Arc::new(String::from("Hello"));
    
thread::spawn(move || { // обрати внимание на move - мы передали владение объектом в поток
  println!("{}", obj);
});
    
println!("{}", obj); // Упс, ошибка borrow of moved value: `obj`

Попробуем передать в поток не объект, а ссылку на него?

let mut obj = Arc::new(String::from("Hello"));

let obj_ref = &mut obj; // И снова упс, `obj` does not live long enough - нельзя чтобы ссылка жила дольше, чем объект
thread::spawn(move || { // тут мы пытаемся передать ссылку на объект на стеке в поток, но поток может жить дольше, чем вызывающая функция. Нет гарантий - компиляция не проходит
  println!("{}", obj_ref);
});
    
println!("{}", obj);

А что можно сделать?

let mut obj = Arc::new(String::from("Hello"));
    
let obj_ref_clone = Arc::clone(&obj); // мы клонируем "умный указатель" и  передаем его
thread::spawn(move || {
  println!("{}", obj_ref_clone);
}).join().unwrap();
    
println!("{}", obj);

Исходная версия hippi90, :

Ок, давай с примерами, а то мы кажется о разном говорим

let mut obj = Arc::new(String::new()); // создаем объект, пусть будет Arc, объявляем его как мутабельный

let a = &obj; // берем обычную ссылку, всё ок
let b = &obj; // берем еще одну обычную ссылку, всё еще ок
let с = &mut obj; // пытаемся взять мутабельную ссылку, получаем ошибку cannot borrow `obj` as mutable because it is also borrowed as immutable

Попробуем в обратном порядке

let mut obj = Arc::new(String::new()); // создаем объект, пусть будет Arc, объявляем его как мутабельный

let a = &mut obj; // берем мутабельную ссылку, всё ок
let b = &obj; // пытаемся взять обычную ссылку, получаем ошибку cannot borrow `obj` as immutable because it is also borrowed as mutable

Давай пример посложнее

let mut obj = Arc::new(String::from("Hello"));
    
thread::spawn(move || { // обрати внимание на move - мы передали владение объектом в поток
  println!("{}", obj);
});
    
println!("{}", obj); // Упс, ошибка borrow of moved value: `obj`

Попробуем передать в поток не объект, а ссылку на него?

let mut obj = Arc::new(String::from("Hello"));

let obj_ref = &mut obj; // И снова упс, `obj` does not live long enough - нельзя чтобы ссылка жила дольше, чем объект
thread::spawn(move || { // обрати внимание на move - мы передали владение объектом в поток
  println!("{}", obj_ref);
});
    
println!("{}", obj);

А что можно сделать?

let mut obj = Arc::new(String::from("Hello"));
    
let obj_ref_clone = Arc::clone(&obj); // мы клонируем "умный указатель" и  передаем его
thread::spawn(move || {
  println!("{}", obj_ref_clone);
}).join().unwrap();
    
println!("{}", obj);