Opublikowano wydanie języka programowania ogólnego przeznaczenia Rust 1.78, 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:
- Zaproponowano nową przestrzeń nazw atrybutów „#[diagnostic]”, zapewniającą możliwość wpływania na komunikaty o błędach generowane przez kompilator. Pierwszym w nowej przestrzeni jest atrybut „#[diagnostic::on_unimplemented]”, którego można użyć do dostosowania komunikatów o błędach zgłaszanych w sytuacji, gdy konieczne jest użycie cechy, która nie jest zaimplementowana dla tego typu. #[diagnostic::on_unimplemented( message = "Moja wiadomość dla `ImportantTrait<{A}>` nie jest zaimplementowana dla `{Self}`", label = "Moja etykieta", note = "Notatka 1", note = "Notatka 2" )] cecha Ważna cecha {} fn use_my_trait(_: impl Ważna cecha ) {} fn main() { use_my_trait(String::new()); } błąd [E32]: Moja wiadomość dla „Ważnej cechy ` nie jest zaimplementowane dla `String` —> src/main.rs:0277:32 | 12 | use_my_trait(String::new()); | ———— ^^^^^^^^^^^^^^ Moja etykieta | | | wymagane przez ograniczenie wprowadzone przez to wywołanie | = pomoc: cecha „Ważna cecha ` nie jest zaimplementowane dla `String` = uwaga: uwaga 18 = uwaga: uwaga 12
- Kontrole wstępne zastosowane do niebezpiecznych funkcji można teraz odłożyć do czasu wygenerowania kodu, dzięki czemu te kontrole można przeprowadzić bez konieczności budowania biblioteki standardowej w trybie „#[cfg(debug_assertions)]”. Aby wyzwolić kontrole, wystarczy teraz włączyć potwierdzenia debugowania dla testów lub kompilacji debugowania kodu.
- Zachowanie funkcji w bibliotece standardowej, które wpływają na wyrównanie wskaźników i wycinków, jest teraz przewidywalne w czasie wykonywania i zależy od danych wejściowych. Funkcja pointer::align_offset, która oblicza przesunięcie w celu wyrównania wskaźnika, zwraca teraz use::MAX tylko wtedy, gdy operacja się nie powiedzie. Funkcje plasterek::align_to i plasterek::align_to_mut, które przekształcają plasterki w reprezentację z wyrównanym środkowym plasterkiem oraz oryginalnymi plasterkami początkowym i końcowym, teraz zawsze zwracają największą środkową część.
- Do kategorii stabilnej przeniesiono:
- impl Odczyt &Stdin
- Zezwalaj na użycie niestatycznego (niestatycznego) czasu życia dla niektórych implementacji związanych z std::error::Error.
- Implementacja impl wolno używać wartości ?Sized.
- impl Od dla io::Błąd
- Funkcja Barrier::new() została ustabilizowana tak, aby można było jej używać z atrybutem „const” w dowolnym kontekście zamiast stałych.
- Dla platform docelowych x86_64-pc-windows-msvc, i686-pc-windows-msvc, x86_64-pc-windows-gnu, i686-pc-windows-gnu, x86_64-pc-windows-gnullvm i i686-pc-windows-gnullvm teraz wymaga co najmniej wersji systemu Windows 10.
- Trzeci poziom wsparcia został wdrożony dla platform wasm32-wasip2, arm64ec-pc-windows-msvc, armv8r-none-eabihf i loongarch64-unknown-linux-musl. Trzeci poziom obejmuje podstawowe wsparcie, ale bez automatycznych testów, publikowania oficjalnych kompilacji i sprawdzania, czy kod da się zbudować.
- Zaimplementowano drugi poziom obsługi platformy docelowej Add wasm32-wasip1. Drugi poziom wsparcia obejmuje gwarancję montażu.
- Nazwę platformy wasm32-wasi-preview1-threads zmieniono na wasm32-wasip1-threads.
- Kompilator został przełączony tak, aby korzystał z LLVM 18. Podczas korzystania z LLVM 18 dla architektur x86-32 i x86-64 zmieniono ABI powiązane z typami u128 i i128.
- W menedżerze paktów Cargo ustabilizowano wersję 4 plików blokujących (lockfile v4).
- Cargo posiada ustabilizowaną globalną pamięć podręczną zawierającą informacje o najnowszym wykorzystaniu danych. Pamięć podręczna jest hostowana w $CARGO_HOME/.global-cache przy użyciu SQLite i jest aktualizowana automatycznie, aby odzwierciedlić najnowsze zmiany w indeksie, pliku skrzyni, katalogu kodu, git clone i git checkout.
Dodatkowo język programowania Borgo stara się być bardziej wyrazisty niż język Go, ale mniej złożony niż język Rust. Borgo łączy w sobie najlepsze cechy Go i Rust, nadrabiając niedociągnięcia każdego języka. Na przykład Go jest prosty i bezpośredni, ale nie zapewnia zaawansowanych funkcji bezpieczeństwa. Język Rust zapewnia narzędzia do bezpiecznego programowania, ale jest zbyt skomplikowany. Projekt rozwija Marco Sampellegrini, autor The Simple Haskell Handbook i twórca systemu ciągłej integracji Quad CI.

Borgo używa typowania statycznego, typów typu Go i składni typu Rust. Średniki na końcu linii w kodzie Borgo są opcjonalne. Kod Borgo jest kompilowany w reprezentację Go, która jest w pełni kompatybilna z istniejącymi pakietami Go. Kod kompilatora napisany jest w języku Rust i jest rozpowszechniany na licencji ISC. użyj fmt enum NetworkState { Ładowanie, niepowodzenie (int), sukces (T), } struct Response { tytuł: string, czas trwania: int, } fn main() { let res = odpowiedź { tytuł: „Witaj świecie”, czas trwania: 0, } niech stan = NetworkState.Success(res) let msg = stan dopasowania { NetworkState.Loading => „wciąż ładuję”, NetworkState.Failed(code) => fmt.Sprintf(„Wystąpił kod błędu: %d”, kod), NetworkState.Success (res) => res.title, } fmt.Println(msg) }
Źródło: opennet.ru
