Как Rust предотвращает скачки данных, когда владелец значения может прочитать его, а другой поток изменяет его? - PullRequest
0 голосов
/ 15 апреля 2019

Книга ржавчины гласит следующее в Ссылки и заимствования

Мы также не можем иметь изменяемую ссылку, пока у нас есть неизменяемая ссылка. Пользователи неизменяемой ссылки не ожидают внезапного изменения значений из-под них! Однако можно использовать несколько неизменных ссылок, потому что никто, кто просто читает данные, не может повлиять на чтение данных кем-либо еще.

Но владелец может читать данные, в то время как другой поток изменяет значение с помощью изменяемого заимствования, верно? Разве у нас не возникает обычная проблема снова или где я неправильно понимаю основную концепцию?

1 Ответ

3 голосов
/ 15 апреля 2019

владелец может читать данные, в то время как другой поток изменяет значение с помощью изменяемого заимствования, верно?

Это неверно, и даже не имеет значения, задействовано ли несколько потоков.

Вы можете убедиться сами в следующем примере ( Детская площадка ). Вот строковое значение x, которое изменяется, сохраняя ссылку на то же значение y:

let mut x = "123".to_string();
let y = &mut x;

x.push_str("456");

println!("y = {}", y);

Не удается скомпилировать:

error[E0499]: cannot borrow `x` as mutable more than once at a time
 --> src/main.rs:5:5
  |
3 |     let y = &mut x;
  |             ------ first mutable borrow occurs here
4 |     
5 |     x.push_str("456");
  |     ^ second mutable borrow occurs here
6 | 
7 |     println!("y = {}", y);
  |                        - first borrow later used here

К тому времени, когда мы пытаемся вызвать push_str, метод, который получает &mut self, предполагается, что новая изменяемая ссылка на значение будет создана на месте. Поскольку x уже был заимствован в этой области, это незаконно.

Теперь вы даже можете подумать о переназначении вместо вызова метода, ожидающего &mut self. Тем не менее, большой шанс:

let mut x = "123".to_string();
let y = &mut x;

x = "321".to_string();

println!("y = {}", y);
error[E0506]: cannot assign to `x` because it is borrowed
 --> src/main.rs:5:5
  |
3 |     let y = &mut x;
  |             ------ borrow of `x` occurs here
4 |     
5 |     x = "321".to_string();
  |     ^ assignment to borrowed `x` occurs here
6 | 
7 |     println!("y = {}", y);
  |                        - borrow later used here

Заимствованная стоимость также не может быть переназначена.

Подводя итог, владелец стоимости по-прежнему ограничен тем, какой вид заимствования был сделан. Если значение было заимствовано неизменно, владелец также может иметь неизменный доступ, но никогда не может быть записано значение в или перемещено , пока заем находится на месте. Когда значение было заимствовано, владелец не может ничего сделать с этим значением, пока эта ссылка не будет удалена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...