Quando "vec!" Crea elementi differenti o no?
Ho appena trovato il seguente codice in 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} }]
collegamento al parco giochi ruggine
Apparentemente v1ha 2 diverse HashMap, mentre ne v2ha solo una. Come è successo? Non dovrebbe v2valutare Arc::new(Mutex::new(HashMap::<i32, i32>::new()))due volte (come v1fare) e quindi creare due elementi diversi? È una sorta di valutazione "pigra" da qualche parte?
Perdonate la mia domanda da principiante ruggine, grazie in anticipo!
Risposte
La vec![value; n]sintassi utilizza Cloneper duplicare il valore e riempire il vettore. I documenti menzionano anche questo tipo di scenario:
Questo userà
cloneper duplicare un'espressione, quindi dovresti stare attento a usarlo con tipi che hannoCloneun'implementazione non standard . Ad esempio,vec![Rc::new(1); 5]creerà un vettore di cinque riferimenti allo stesso valore intero boxed, non cinque riferimenti che puntano a interi boxed indipendentemente.
La vec!macro clona il valore dell'espressione fornita per riempire il vettore fino alla lunghezza richiesta.
An Arcè un puntatore intelligente con conteggio dei riferimenti, condiviso dalla clonazione. Ogni volta che si clona un Arc, aumenta il conteggio dei riferimenti ai dati sottostanti, ma i dati sottostanti sono sempre gli stessi.
Quindi questo è ciò che sta accadendo nel tuo esempio. Gli elementi del vettore sono diversi puntatori allo stesso HashMap.