Замена заимствованной переменной

У меня есть ведро объектов, которые должны накапливать значения. Он защищенRwLockи как таковой я также держу вокруг его блокировки записи. Я хочу сохранить одну блокировку записи на время процесса.

Например:

use std::sync::RwLock;

fn main() {
    let locked = RwLock::new(Vec::<u32>::new());

    // this is the entry point for real-world code
    let mut writer = locked.write().unwrap();    

    // copy into 'locked' until it is full (has 4 items)
    for v in 0..100 {
        if writer.len() > 4 {
            // discard 'writer' and 'locked', create anew
            locked = RwLock::new(Vec::<u32>::new());
            writer = locked.write().unwrap();
        }
        writer.push(v);
    }
}

В то время как мой пример работает с фиксированными данными, и поэтому, похоже, не нуждается вRwLock вообще, реальный код будет входить в «реальный код» и не обязательно выходить на границеlocked становится "полным".

Как мне создать новыйlocked а такжеwriter возражать когда нужно без заемщика-несогласного?

 Shepmaster04 авг. 2016 г., 22:39
Я вижу ваш отказ от ответственности, но я все еще не понимаю вашу программу. Если вы удерживаете блокировку записи на время всей программы, тогда блокировка чтения никогда не будет получена, поэтому на самом деле нет возможности для многопоточности ...
 David Grayson04 авг. 2016 г., 22:16
Я не понимаю, почему вы должны отказаться от вектора и блокировки вокруг него. Почему бы просто не изменить его размер на ноль, чтобы отбросить все данные в нем?

Ответы на вопрос(1)

согласенс Дэвидом ГрейсономНет очевидной необходимости воссоздаватьRwLock, Предполагая, что вам нужен вектор после заполнения, используйтеmem::replace выключитьVec:

use std::sync::RwLock;
use std::mem;

fn main() {
    let locked = RwLock::new(Vec::<u32>::new());
    let mut writer = locked.write().unwrap();    

    for v in 0..100 {
        if writer.len() > 4 {
            let old_vec = mem::replace(&mut *writer, Vec::new());
        }
        writer.push(v);
    }
}

Если вам не нужноVecтогда просто позвониVec::clear.

 njaard05 авг. 2016 г., 01:27
mem::replace задокументировано как не копирующий ни один из его параметров, но его исходный код используетиспользуя copy_non_overlapping, Мне нужен этот код для работы сDrop и неясно, когда мне позволят это сделать. Я создал новый вопрос здесь.
 durka4223 авг. 2016 г., 18:04
Я думаю, что в документации должно быть сказано «без клонирования» или «без глубокого копирования».mem::replace звонкиmem::swap который правильно используетmem::forget чтобы избежать лишних капель, чтобы у вас не было проблем. Во всяком случае код в этом ответе не упоминаетсяunsafeтак что вы знаете, что у него не будет лишних капель, даже не глядя на источник :)

Ваш ответ на вопрос