У коллекций 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 знает, как очистить строку, когда он очищает вектор.