Как изменить переменную Cow, которая использует себя в цикле? - PullRequest
0 голосов
/ 14 апреля 2019

Я пытаюсь удалить все скобки в строке.Не задумываясь об этом, я просто заменяю регулярное выражение (то есть, проблема не в том, чтобы избавиться от произвольных уровней вложенных скобок, но вы можете предложить лучший способ сделать это в комментарии, если хотите).).

use regex::Regex;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let input = "Text (with some (nested) parentheses)!";
    let re = Regex::new(r"\([^()]*\)")?;

    let output = re.replace_all(&input, "");
    let output = re.replace_all(&output, "");
    //    let output = re.replace_all(&output, "");
    //    let output = re.replace_all(&output, "");
    //    let output = re.replace_all(&output, "");
    //    let output = re.replace_all(&output, "");
    // ...

    assert_eq!("Text !", output);

    println!("Works!");

    Ok(())
}

Поскольку я не знаю, какими будут вложенные скобки, мне нужно выполнять замену в цикле, а не повторять ее «достаточно раз».Однако создание цикла создает новую область видимости, и именно здесь я зашел в тупик в обсуждении с помощью средства проверки заимствования.

Простейший случай, который показывает, что я пытаюсь сделать в цикле, будет:

    let mut output = re.replace_all(&input, "");
    while re.is_match(&output) {
        output = re.replace_all(&output, "");
    }

Однако этого нельзя сделать, потому что я присваиваю заемную переменную:

error[E0506]: cannot assign to `output` because it is borrowed
 --> src/main.rs:9:9
  |
9 |         output = re.replace_all(&output, "");
  |         ^^^^^^                  ------- borrow of `output` occurs here
  |         |
  |         assignment to borrowed `output` occurs here
  |         borrow later used here

В идеале я хотел бы создать новую привязку переменной с помощьюто же имя, но использование let output = будет скрывать привязку внешней переменной, поэтому цикл будет циклически бесконечным.

Независимо от того, какую внутреннюю или внешнюю временную переменную я создаю, я не могу заставить ее делать то, что я хочу.Я также пытался использовать тот факт, что re.replace_all() возвращает Cow, и пытался использовать .to_owned() и .to_string() в нескольких местах, но это тоже не помогло.

Вот ссылка на игровую площадку .

1 Ответ

1 голос
/ 14 апреля 2019

re.replace_all() возвращает Cow

Это корень проблемы.Компилятор знает, что возвращаемое значение может ссылаться на output, но также будет заменять output, вызывая немедленное отбрасывание output.Если бы это позволило, ссылка указала бы на нераспределенную память, что привело к небезопасной памяти.

Решение состоит в том, чтобы вообще избежать заимствования.

попытался использовать .to_owned()

to_owned на Cow просто возвращает тот же Cow.Возможно, вы имели в виду into_owned?

let mut output = re.replace_all(&input, "").into_owned();
while re.is_match(&output) {
    output = re.replace_all(&output, "").into_owned();
}

и .to_string() в нескольких местах

Это также работает:

let mut output = re.replace_all(&input, "").to_string();
while re.is_match(&output) {
    output = re.replace_all(&output, "").to_string();
}

Жаль, что вы не показали свои реальные попытки решить проблему, мы могли бы помочь вам понять, почему они не сработали.

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