Випуск Rust 1.78. Мова Borgo, що поєднує сильні сторони Go та Rust

Опубліковано реліз мови програмування загального призначення Rust 1.78, заснованого проектом Mozilla, але нині розвивається під заступництвом незалежної некомерційної організації Rust Foundation. Мова сфокусована на безпечній роботі з пам'яттю та надає засоби для досягнення високого паралелізму виконання завдань, при цьому обходячись без використання збирача сміття та runtime (runtime зводиться до базової ініціалізації та супроводу стандартної бібліотеки).

Методи роботи з пам'яттю в Rust позбавляють розробника помилок при маніпулюванні покажчиками і захищають від проблем, що виникають через низькорівневу роботу з пам'яттю, таких як звернення до області пам'яті після її звільнення, розіменування нульових покажчиків, вихід за межі буфера і т.п. Для поширення бібліотек, забезпечення збирання та управління залежностями проектом розвивається пакетний менеджер Cargo. Для розміщення бібліотеки підтримується репозиторій crates.io.

Безпечна робота з пам'яттю забезпечується в Rust під час компіляції через перевірку посилань, відстеження володіння об'єктами, облік часу життя об'єктів (області видимості) та оцінку коректності доступу до пам'яті під час виконання коду. Rust також надає засоби для захисту від цілих переповнень, вимагає обов'язкової ініціалізації значень змінних перед використанням, краще обробляє помилки в стандартній бібліотеці, застосовує концепцію незмінності посилань і змінних за умовчанням, пропонує сильну статичну типізацію для мінімізації логічних помилок.

Основні нововведення:

  • Запропоновано новий простір імен атрибутів «#[diagnostic]», що надає засоби для впливу повідомлення про помилки, що видаються компілятором. Першим у новому просторі реалізований атрибут "#[diagnostic::on_unimplemented]", який може використовуватися для налаштування повідомлень про помилки, що видаються в ситуації, коли потрібно використовувати типаж, який не реалізований для типу. #[diagnostic::on_unimplemented( message = "My Message for `ImportantTrait<{A}>` is not implemented for `{Self}`", label = "My Label", note = "Note 1", note = "Note 2» )] trait ImportantTrait {} fn use_my_trait(_: impl ImportantTrait ) {} fn main() { use_my_trait(String::new()); } error[E32]: My Message for `ImportantTrait ` is not implemented for `String` -> src/main.rs:0277:32 | 12 | use_my_trait(String::new()); | ———— ^^^^^^^^^^^^^^ My Label | | | required by a bound introduced by this call | = help: the trait `ImportantTrait ` is not implemented for `String` = note: Note 18 = note: Note 12
  • Попередні assert-перевірки, що застосовуються до unsafe-функцій, тепер можуть відкладатися до стадії генерації коду, що дозволяє виконувати дані перевірки без необхідності збирання стандартної бібліотеки в режимі #[cfg(debug_assertions)]. Для спрацювання перевірок тепер достатньо включення налагоджувальних assert-ів для тестових або налагоджувальних складання свого коду.
  • Поведінка функцій у стандартній бібліотеці, що впливають на вирівнювання покажчиків та зрізів (slice), тепер передбачувана під час виконання та залежить від вхідних даних. Функція pointer::align_offset, що обчислює зміщення для вирівнювання покажчика, тепер повертає usize::MAX лише за неможливості виконання операції. Функції slice::align_to і slice::align_to_mut both, що перетворюють зрізи у виставу з вирівняним середнім зрізом і вихідними початковим і кінцевим зрізами, тепер завжди повертають найбільшу середню частину.
  • У розряд стабільних переведено:
    • impl Read for &Stdin
    • Дозволено використання нестатичного (не 'static) часу життя для деяких реалізацій, пов'язаних із std::error::Error.
    • У реалізації impl дозволено використання значення ?Sized.
    • impl From for io::Error
  • Функція Barrier::new() стабілізована для використання з ознакою «const» у будь-якому контексті замість констант.
  • Для цільових платформ x86_64-pc-windows-msvc, i686-pc-windows-msvc, x86_64-pc-windows-gnu, i686-pc-windows-gnu, x86_64-pc-windows-gnullvm-і тепер потрібно як мінімум версія Windows 686.
  • Реалізовано третій рівень підтримки для платформ wasm32-wasip2, arm64ec-pc-windows-msvc, armv8r-none-eabihf та loongarch64-unknown-linux-musl. Третій рівень передбачає базову підтримку, але без автоматизованого тестування, публікації офіційних збірок та перевірки можливості складання коду.
  • Реалізовано другий рівень підтримки цільової платформи Add wasm32-wasip1. Другий рівень підтримки передбачає гарантію складання.
  • Платформа wasm32-wasi-preview1-threads перейменована на wasm32-wasip1-threads.
  • Компілятор переведено на використання LLVM 18. При використанні LLVM 18 для архітектур x86-32 та x86-64 змінено ABI, пов'язане з типами u128 та i128.
  • У пактом менеджері Cargo стабілізовано 4 версію файлів-блокувань (lockfile v4).
  • У Cargo стабілізовано глобальний кеш з інформацією про останнє використання даних. Кеш розміщується у файлі $CARGO_HOME/.global-cache за допомогою SQLite, оновлюється автоматично та відображає останні зміни, пов'язані з індексом, crate-файлом, каталогом з кодом, git clone та git checkout.

Додатково можна відзначити мову програмування Borgo, яка намагається бути виразнішою, ніж мова Go, але менш складною, ніж мова Rust. Borgo комбінує найкращі риси Go і Rust, заповнюючи недоліки кожної мови. Наприклад, мова Go проста і зрозуміла, але не надає розширених засобів для забезпечення безпеки при роботі з типами. Мова Rust надає засоби для безпечного програмування, але переускладнена. Проект розвиває Marco Sampellegrini, автор книги The Simple Haskell Handbook і розробник системи безперервної інтеграції Quad CI.

Випуск Rust 1.78. Мова Borgo, що поєднує сильні сторони Go та Rust

У Borgo використовується статична типізація, аналогічні мові Go типи та синтаксис, схожий на Rust. Вказівка ​​точок з комою в кінці рядків у коді на Borgo не є обов'язковою. Код на мові Borgo компілюється у подання на мові Go, яка повністю сумісна з наявними пакетами для мови Go. Код компілятора написаний мовою Rust та поширюється під ліцензією ISC. use fmt enum NetworkState { Loading, Failed(int), Success(T), } struct Response { title: string, duration: int, } fn main() { let res = Response { title: "Hello world", duration: 0, } let state = NetworkState.Success(res) let msg = match state { NetworkState.Loading => still loading, NetworkState.Failed(code) => fmt.Sprintf("Got error code: %d", code) (res) => res.title, } fmt.Println(msg) }

Джерело: opennet.ru

Додати коментар або відгук