История изменений
Исправление 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);