У коллекций Rust есть возможность владеть данными, которые они хранят?

Учитывая следующий код (который не компилируется):

fn main() {
    let mut v = vec!();

    {
        let name = "Bob the Builder".to_string();

        v.push(&name);
    }

    for m in &v{
        println!("{}", m);
    }
}

Я создал переменную привязку к Rust String тип, который выйдет за рамки первого набора фигурных скобок. Есть ли способ как-то переместить владение String так, чтобы оно принадлежало самому вектору?

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

Я уже знаю, что если я использую строковый литерал, это будет рассматриваться как статическая строка, которая будет существовать в течение всего жизненного цикла приложения, и поэтому этот код будет компилироваться, но я просто пытаюсь понять, может ли коллекция в Rust иметь данные, Я знаю, что Rust не является Objective-C, но у Objective-C есть коллекции с возможностью сохранять свои данные.

1 ответ

Решение

Вектор будет принадлежать ему... до тех пор, пока вы не передадите ссылку на него.

Изменение вашего кода на это:

fn main() {
    let mut v = vec!();
    {
        let name = "Bob the Builder".to_string();

        v.push(name); // <--- no ampersand

        println!("{}", name); // <---- error, use of moved value
    }

    for m in &v {
        println!("{}", m);
    }
}

..бросает ошибку, потому что name теперь принадлежит вектору. Если вы учитываете тот факт, что Вектор теперь владеет строкой.. ваш код компилируется (удаляя мой println! вызов):

fn main() {
    let mut v = vec!();
    {
        let name = "Bob the Builder".to_string();

        v.push(name); // <--- no ampersand
    }

    for m in &v {
        println!("{}", m); // <--- works fine
    }
}

Итак, ваша проблема в том, что вы передаете ссылку на вашу строку в вектор. По сути, в конце блока ваш name значение будет снижено, и ваш &name ссылка в векторе потенциально может указывать на неверную память.. делая v[0].something_here() потенциально опасный Таким образом, компилятор останавливает вас. Но, если вы передадите право собственности на name переменная в вектор (не передавая ссылку.. но передавая все это), тогда Rust знает, как очистить строку, когда он очищает вектор.

Другие вопросы по тегам