Opublikowano wydanie języka programowania ogólnego przeznaczenia Rust 1.75, stworzonego w ramach projektu Mozilla, ale obecnie rozwijanego pod auspicjami niezależnej organizacji non-profit Rust Foundation. Język koncentruje się na bezpieczeństwie pamięci i zapewnia środki do osiągnięcia wysokiej równoległości zadań przy jednoczesnym uniknięciu korzystania z modułu wyrzucania elementów bezużytecznych i środowiska uruchomieniowego (czas działania jest ograniczony do podstawowej inicjalizacji i konserwacji standardowej biblioteki).
Metody obsługi pamięci Rust chronią programistę przed błędami podczas manipulowania wskaźnikami i chronią przed problemami wynikającymi z obsługi pamięci niskiego poziomu, takimi jak dostęp do obszaru pamięci po jego zwolnieniu, dereferencja pustych wskaźników, przepełnienie bufora itp. Aby dystrybuować biblioteki, dostarczać kompilacje i zarządzać zależnościami, projekt rozwija menedżera pakietów Cargo. Repozytorium crates.io jest obsługiwane w przypadku bibliotek hostingowych.
Bezpieczeństwo pamięci w Rust jest zapewnione w czasie kompilacji poprzez sprawdzanie referencji, śledzenie własności obiektów, śledzenie czasu życia obiektów (zakresów) i ocenę poprawności dostępu do pamięci podczas wykonywania kodu. Rust zapewnia również ochronę przed przepełnieniami liczb całkowitych, wymaga obowiązkowej inicjalizacji wartości zmiennych przed użyciem, lepiej radzi sobie z błędami w standardowej bibliotece, domyślnie stosuje koncepcję niezmiennych odniesień i zmiennych, oferuje silne typowanie statyczne w celu zminimalizowania błędów logicznych.
Główne innowacje:
- Dodano możliwość używania „async fn” i notacji „->impl Cecha” w cechach prywatnych. Na przykład, używając „->impl Cecha” możesz napisać metodę cechy, która zwraca iterator: cecha Kontener { fn items(&self) -> impl Iterator; } impl Kontener dla MyContainer { fn items(&self) -> impl Iterator { self.items.iter().cloned() } }
Możesz także tworzyć cechy za pomocą „async fn”: cecha HttpService { async fn fetch(&self, url: Url) -> HtmlBody; // zostanie rozwinięte do: // fn fetch(&self, url: Url) -> impl Future; }
- Dodano API do obliczania przesunięć bajtów względem wskaźników. Podczas pracy z gołymi wskaźnikami („*const T” i „*mut T”) mogą być wymagane operacje w celu dodania przesunięcia do wskaźnika. Poprzednio można było w tym celu zastosować konstrukcję typu „::add(1)”, dodając liczbę bajtów odpowiadającą rozmiarowi „size_of::()”. Nowe API upraszcza tę operację i umożliwia manipulowanie przesunięciami bajtów bez uprzedniego rzutowania typów na „*const u8” lub „*mut u8”.
- wskaźnik::byte_add
- wskaźnik::przesunięcie_bajtu
- wskaźnik::byte_offset_from
- wskaźnik::byte_sub
- wskaźnik::wrapping_byte_add
- wskaźnik::wrapping_byte_offset
- wskaźnik::wrapping_byte_sub
- Kontynuowano prace nad zwiększeniem wydajności kompilatora rustc. Dodano optymalizator BOLT, który działa na etapie post-link i wykorzystuje informacje z wcześniej przygotowanego profilu wykonania. Użycie BOLT pozwala przyspieszyć wykonanie kompilatora o około 2% poprzez zmianę układu kodu biblioteki librustc_driver.so w celu efektywniejszego wykorzystania pamięci podręcznej procesora.
Włączono budowanie kompilatora rustc z opcją „-Ccodegen-units=1”, aby poprawić jakość optymalizacji w LLVM. Przeprowadzone testy wykazały wzrost wydajności w przypadku kompilacji „-Ccodegen-units=1” o około 1.5%. Dodane optymalizacje są domyślnie włączone tylko dla platformy x86_64-unknown-linux-gnu.
Wspomniane wcześniej optymalizacje zostały przetestowane przez Google, aby skrócić czas budowy komponentów platformy Android napisanych w języku Rust. Użycie „-C codegen-units=1” podczas budowania Androida pozwoliło nam zmniejszyć rozmiar zestawu narzędzi o 5.5% i zwiększyć jego wydajność o 1.8%, podczas gdy czas budowy samego zestawu narzędzi prawie się podwoił.
Włączenie usuwania elementów bezużytecznych w czasie łącza („--gc-sections”) przyniosło wzrost wydajności do 1.9%, umożliwiło optymalizację czasu łącza (LTO) do 7.7%, a optymalizację opartą na profilach (PGO) do 19.8%. W finale zastosowano optymalizacje za pomocą narzędzia BOLT, co umożliwiło zwiększenie szybkości kompilacji do 24.7%, ale rozmiar zestawu narzędzi wzrósł o 10.9%.
- Nowa część API została przeniesiona do kategorii stabilnej, w tym metody i implementacje cech zostały ustabilizowane:
- Atomowy*::from_ptr
- PlikTimes
- FileTimesExt
- Plik::set_modified
- Plik::set_times
- IpAddr::to_canonical
- Adres IPv6::to_canonical
- Opcja::as_slice
- Opcja::as_mut_slice
- wskaźnik::byte_add
- wskaźnik::przesunięcie_bajtu
- wskaźnik::byte_offset_from
- wskaźnik::byte_sub
- wskaźnik::wrapping_byte_add
- wskaźnik::wrapping_byte_offset
- wskaźnik::wrapping_byte_sub
- Atrybut „const”, który określa możliwość użycia go w dowolnym kontekście zamiast stałych, jest używany w funkcjach:
- Adres IPv6::to_ipv4_mapped
- MaybeUninit::assume_init_read
- MożeUninit::zero
- mem::dyskryminujący
- mem::wyzerowany
- Trzeci poziom wsparcia został zaimplementowany dla platform csky-unknown-linux-gnuabiv2hf, i586-unknown-netbsd i mipsel-unknown-netbsd. Trzeci poziom obejmuje podstawowe wsparcie, ale bez automatycznych testów, publikowania oficjalnych kompilacji i sprawdzania, czy kod da się zbudować.
Dodatkowo możemy zauważyć nową wersję projektu Hermit, który rozwija specjalizowane jądro (unikernel), napisane w języku Rust, dostarczające narzędzia do budowy samodzielnych aplikacji, które mogą działać na hypervisorze lub na gołym sprzęcie bez dodatkowych warstw i bez systemu operacyjnego. Po zbudowaniu aplikacja jest statycznie połączona z biblioteką, która niezależnie implementuje całą niezbędną funkcjonalność, bez powiązania z jądrem systemu operacyjnego i bibliotekami systemowymi. Kod projektu jest rozpowszechniany na licencjach Apache 2.0 i MIT. Asembler jest obsługiwany w przypadku samodzielnego wykonywania aplikacji napisanych w językach Rust, Go, Fortran, C i C++. Projekt opracowuje także własny bootloader, który umożliwia uruchomienie Hermita przy użyciu QEMU i KVM.
Źródło: opennet.ru