È stato pubblicato il rilascio del linguaggio di programmazione Rust 1.53, originariamente sviluppato da Mozilla, ma ora portato avanti sotto l'egida di una fondazione no profit indipendente, la Rust Foundation. Questo linguaggio si concentra su un uso sicuro della memoria, garantendo una gestione automatica della memoria e fornendo strumenti per raggiungere un elevato parallelismo nelle esecuzioni, senza necessitare di un garbage collector e con un runtime limitato alla sola inizializzazione e all'accompagnamento della libreria standard.
La gestione automatica della memoria in Rust solleva gli sviluppatori dagli errori nella manipolazione dei puntatori e protegge da problemi derivanti dal lavoro a basso livello con la memoria, come l'accesso a aree di memoria già liberate, la dereferenziazione di puntatori nulli, il superamento dei limiti di un buffer, ecc. Per la distribuzione delle librerie, la costruzione e la gestione delle dipendenze, è in fase di sviluppo il gestore di pacchetti Cargo. Per l'hosting delle librerie, è supportato il repository crates.io.
Novità principali:
- Per gli array è stato implementato il trait IntoIterator, che consente di iterare sugli elementi di un array per valore: for i in [1, 2, 3] { .. }
È inoltre possibile passare gli array ai metodi che accettano iteratori, ad esempio: let set = BTreeSet::from_iter([1, 2, 3]); for (a, b) in some_iterator.chain([1]).zip([1, 2, 3]) { .. }
In precedenza, IntoIterator era implementato solo per riferimenti a array, ovvero per iterare sui valori era necessario utilizzare riferimenti («&[1, 2, 3]») o «[1, 2, 3].iter()». Le implementazioni di IntoIterator per gli array erano ostacolate da problemi di compatibilità causati dalla conversione del metodo array.into_iter() in (&array).into_iter() già presente nel compilatore. Questi problemi sono stati risolti in modo indiretto: il compilatore continuerà a convertire array.into_iter() in (&array).into_iter() come se l'implementazione del tipo IntoIterator non fosse presente, ma solo quando si chiama il metodo utilizzando la sintassi «.into_iter()» e senza toccare le chiamate nella forma «in [1, 2, 3]», «iter.zip([1, 2, 3])», «IntoIterator::into_iter([1, 2, 3])».
- È stata fornita la possibilità di specificare espressioni «|» (operazione logica OR) in qualsiasi parte del modello, ad esempio, invece di «Some(1) | Some(2)» ora si può scrivere «Some(1 | 2)»: match result { Ok(Some(1 | 2)) => { .. } Err(MyError { kind: FileNotFound | PermissionDenied, .. }) => { .. } _ => { .. } }
- È consentito l'uso di caratteri non-ASCII negli identificatori, inclusi qualsiasi simbolo nazionale definito nella specifica Unicode UAX 31, ad eccezione dei simboli emoji. Quando si utilizzano simboli diversi ma simili nell'aspetto, il compilatore emetterà un avviso. const BLÅHAJ: &str = «🦈»; struct 人 { 名字: String, } let α = 1; let sos = 2; warning: identificatore coppia considerato confondibile tra ‘s’ e ‘s’
- È stata tradotta una nuova porzione di API nella categoria stabile, tra cui sono stati stabilizzati:
- array::from_ref
- array::from_mut
- AtomicBool::fetch_update
- AtomicPtr::fetch_update
- BTreeSet::retain
- BTreeMap::retain
- BufReader::seek_relative
- cmp::min_by
- cmp::min_by_key
- cmp::max_by
- cmp::max_by_key
- DebugStruct::finish_non_exhaustive
- Duration::ZERO
- Duration::MAX
- Duration::is_zero
- Duration::saturating_add
- Duration::saturating_sub
- Duration::saturating_mul
- f32::is_subnormal
- f64::is_subnormal
- IntoIterator per array
- {integer}::BITS
- io::Error::Unsupported
- NonZero*::leading_zeros
- NonZero*::trailing_zeros
- Option::insert
- Ordering::is_eq
- Ordering::is_ne
- Ordering::is_lt
- Ordering::is_gt
- Ordering::is_le
- Ordering::is_ge
- OsStr::make_ascii_lowercase
- OsStr::make_ascii_uppercase
- OsStr::to_ascii_lowercase
- OsStr::to_ascii_uppercase
- OsStr::is_ascii
- OsStr::eq_ignore_ascii_case
- Peekable::peek_mut
- Rc::increment_strong_count
- Rc::decrement_strong_count
- slice::IterMut::as_slice
- AsRef<[T]> per slice::IterMut
- impl SliceIndex per (Bound<usize>, Bound<usize>)
- Vec::extend_from_within
- È stato realizzato il terzo livello di supporto per la piattaforma wasm64-unknown-unknown. Il terzo livello prevede un supporto di base, ma senza test automatizzati, pubblicazione di versioni ufficiali e verifica della possibilità di compilazione del codice.
- Il gestore pacchetti Cargo è stato modificato per utilizzare "main" come nome principale per il ramo del repository Git (HEAD) per impostazione predefinita. Non è più necessario specificare branch = "main" per le dipendenze in repository che utilizzano il nome main invece di master.
- Nel compilatore, i requisiti per la versione minima di LLVM sono stati innalzati a LLVM 10.
In aggiunta, si può notare il finanziamento per lo sviluppo dell'integrazione nel kernel Linux di strumenti per lo sviluppo di componenti in linguaggio Rust. Il lavoro verrà svolto nell'ambito del progetto Prossimo sotto l'egida dell'organizzazione ISRG (Internet Security Research Group), che è il fondatore del progetto Let's Encrypt e promuove l'adozione di HTTPS e lo sviluppo di tecnologie per aumentare la sicurezza di Internet. I fondi saranno forniti da Google, che pagherà il lavoro di Miguel Ojeda, autore del progetto Rust-for-Linux. In precedenza, ISRG e Google hanno già finanziato la creazione di un backend HTTP alternativo per lo strumento curl e lo sviluppo di un nuovo modulo TLS per il server web Apache.
Secondo i dati di Microsoft e Google, circa il 70% delle vulnerabilità è causato da operazioni non sicure con la memoria. Si prevede che l'uso del linguaggio Rust per lo sviluppo di componenti del kernel, come i driver dei dispositivi, possa ridurre il rischio di vulnerabilità causate da operazioni non sicure con la memoria ed eliminare errori come l'accesso a memoria liberata e il superamento dei limiti del buffer.
La gestione sicura della memoria in Rust viene garantita durante la compilazione tramite il controllo dei riferimenti, il tracciamento della proprietà degli oggetti e la gestione del tempo di vita degli oggetti (scope), nonché tramite la valutazione della correttezza dell'accesso alla memoria durante l'esecuzione del codice. Rust fornisce anche strumenti per proteggere contro i sovraccarichi numerici, richiede l'inizializzazione obbligatoria dei valori delle variabili prima dell'uso, gestisce meglio gli errori nella libreria standard, applica il concetto di riferimenti e variabili immutabili (immutable) per impostazione predefinita e offre una forte tipizzazione statica per minimizzare gli errori logici.
Fonte: opennet.ru
