Когда vec! Создает разные элементы или нет?
Я только что наткнулся на следующий код в Rust:
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
fn main() {
let mut v1 = vec![HashMap::<i32, i32>::new(); 2];
v1[0].insert(0,0);
v1[1].insert(1,1);
println!("{:?}", v1);
let v2 = vec![Arc::new(Mutex::new(HashMap::<i32, i32>::new())); 2];
v2[0].lock().unwrap().insert(0,0);
v2[1].lock().unwrap().insert(1,1);
println!("{:?}", v2);
}
// outputs:
// [{0: 0}, {1: 1}]
// [Mutex { data: {0: 0, 1: 1} }, Mutex { data: {0: 0, 1: 1} }]
ссылка на ржавую площадку
По-видимому, у v1него есть 2 разных HashMap, а у v2него только одна. Как это случилось? Не следует v2оценивать Arc::new(Mutex::new(HashMap::<i32, i32>::new()))дважды (например, v1do) и, таким образом, создавать два разных элемента? Это где-то «ленивая» оценка?
Простите мой вопрос новичку по ржавчине, заранее спасибо!
Ответы
vec![value; n]Синтаксис используется , Cloneчтобы дублировать значение и заполнить вектор. В документах даже упоминается такой сценарий:
Это будет использоваться
cloneдля дублирования выражения, поэтому следует быть осторожным при использовании этого с типами, имеющими нестандартнуюCloneреализацию. Например,vec![Rc::new(1); 5]будет создан вектор из пяти ссылок на одно и то же целочисленное значение в рамке, а не из пяти ссылок, указывающих на независимо упакованные целые числа.
В vec!макро - клоны ценность предоставленного выражения для заполнения вектора до требуемой длины.
An Arc- это умный указатель с подсчетом ссылок, который используется при клонировании. Каждый раз, когда вы клонируете объект Arc, он увеличивает счетчик ссылок на базовые данные, но базовые данные остаются прежними.
Вот что происходит в вашем примере. Элементы вектора - это разные указатели на одно и то же HashMap.