Выпуск Rust 1.78. Язык Borgo, сочетающий сильные стороны Go и Rust
Опубликован релиз языка программирования общего назначения Rust 1.78, основанного проектом Mozilla, но ныне развиваемого под покровительством независимой некоммерческой организации Rust Foundation. Язык сфокусирован на безопасной работе с памятью и предоставляет средства для достижения высокого параллелизма выполнения заданий, при этом обходясь без использования сборщика мусора и runtime (runtime сводится к базовой инициализации и сопровождению стандартной библиотеки).
Методы работы с памятью в Rust избавляют разработчика от ошибок при манипулировании указателями и защищают от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п. Для распространения библиотек, обеспечения сборки и управления зависимостями проектом развивается пакетный менеджер Cargo. Для размещения библиотек поддерживается репозиторий crates.io.
Безопасная работа с памятью обеспечивается в Rust во время компиляции через проверку ссылок, отслеживание владения объектами, учёт времени жизни объектов (области видимости) и оценку корректности доступа к памяти во время выполнения кода. Rust также предоставляет средства для защиты от целочисленных переполнений, требует обязательной инициализации значений переменных перед использованием, лучше обрабатывает ошибки в стандартной библиотеке, применяет концепцию неизменяемости (immutable) ссылок и переменных по умолчанию, предлагает сильную статическую типизацию для минимизации логических ошибок.
Основные новшества:
- Предложено новое пространство имён атрибутов »#[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‹A› {} fn use_my_trait(_: impl ImportantTrait‹i32›) {} fn main() { use_my_trait(String::new()); } error[E0277]: My Message for `ImportantTrait‹i32›` is not implemented for `String` --> src/main.rs:12:18 | 12 | use_my_trait(String::new()); | ------------ ^^^^^^^^^^^^^ My Label | | | required by a bound introduced by this call | = help: the trait `ImportantTrait‹i32›` is not implemented for `String` = note: Note 1 = note: Note 2
Предварительные 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‹Fd: AsFd›
разрешено использование значения?Sized
. -
impl From‹TryReserveError› 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 и i686-pc-windows-gnullvm теперь требуется как минимум версия Windows 10.
Реализован третий уровень поддержки для платформ 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 cтабилизирован глобальный кэш с информацией о последнем использовании данных. Кэш размещается в файле $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.
В Borgo используется статическая типизация, аналогичные языку Go типы и синтаксис, похожий на Rust. Указание точек с запятой в конце строк в коде на Borgo не является обязательным. Код на языке Borgo компилируется в представление на языке Go, которое полностью совместимо с существующими пакетами для языка Go. Код компилятора написан на языке Rust и распространяется под лицензией ISC.
use fmt enum NetworkState‹T› { 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), NetworkState.Success(res) => res.title, } fmt.Println(msg) }
Источник: http://www.opennet.ru/opennews/art.shtml? num=61104
© OpenNet