Методы работы с памятью в Rust избавляют разработчика от ошибок при манипулировании указателями и защищают от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п. Для распространения библиотек, обеспечения сборки и управления зависимостями проектом развивается пакетный менеджер Cargo. Для размещения библиотек поддерживается репозиторий crates.io.
Безопасная работа с памятью обеспечивается в Rust во время компиляции через проверку ссылок, отслеживание владения объектами, учёт времени жизни объектов (области видимости) и оценку корректности доступа к памяти во время выполнения кода. Rust также предоставляет средства для защиты от целочисленных переполнений, требует обязательной инициализации значений переменных перед использованием, лучше обрабатывает ошибки в стандартной библиотеке, применяет концепцию неизменяемости (immutable) ссылок и переменных по умолчанию, предлагает сильную статическую типизацию для минимизации логических ошибок.
Основные новшества:
- В стандартную библиотеку добавлена поддержка неименованных каналов (anonymous pipe). Для создания неименованных каналов предложен метод
std::io::pipe(), который может использоваться в сочетании с std::process::Command для обработки стандартных входных и выходных потоков, а также для объединения потоков stdout и stderr.Код:
use std::process::Command;
use std::io::Read;
let (mut recv, send) = std::io::pipe()?;
let mut command = Command::new("path/to/bin")
// объединение stdout и stderr в один канал
.stdout(send.try_clone()?)
.stderr(send)
.spawn()?;
let mut output = Vec::new();
recv.read_to_end(&mut output)?;
assert!(command.wait()?.success()); - Разрешён вызов из safe-кода большинства встроенных в компилятор функций (Intrinsics) std::arch. Изменение применяется к встроенным функциям std::arch, которые помечены unsafe только из-за привязки к определённой функциональности, если эта функциональность включена. Например, _mm256_add_epi32 можно вызывать из safe-кода, если в приложении используется '#[target_feature(enable = "avx2")]'.
- Из блоков "asm!" с ассемблерным кодом разрешено осуществлять переходы на блоки с кодом на языке Rust, что упрощает разработку низкоуровневого кода, например, реализации оптимизаций в ядре или организации взаимодействия с оборудованием. Точка для перехода для ассемблерной команды "jmp" задаётся в макросе "asm!" при помощи нового операнда "label", содержащего блочное выражение с кодом на языке Rust.
Код:
unsafe {
asm!(
"jmp {}",
label {
println!("Jumped from asm!");
}
);
} - Разрешено точно указывать захваченные обобщённые типы и время жизни в определениях типажей с использованием возвращаемых типов impl Trait.
Код:
trait Foo {
fn method‹'a›(&'a self) -› impl Sized;
type Implicit1‹'a›: Sized;
fn method_desugared‹'a›(&'a self) -› Self::Implicit1‹'a›;
fn precise‹'a›(&'a self) -> impl Sized + use‹Self›;
type Implicit2: Sized;
fn precise_desugared‹'a›(&'a self) -› Self::Implicit2;
} - В разряд стабильных переведена новая порция API, в том числе стабилизированы методы и реализации типажей:
- Vec::extract_if
- vec::ExtractIf
- LinkedList::extract_if
- linked_list::ExtractIf
- ‹[T]›::split_off
- ‹[T]›::split_off_mut
- ‹[T]›::split_off_first
- ‹[T]›::split_off_first_mut
- ‹[T]›::split_off_last
- ‹[T]›::split_off_last_mut
- String::extend_from_within
- os_str::Display
- OsString::display
- OsStr::display
- io::pipe
- io::PipeReader
- io::PipeWriter
- impl From‹PipeReader› for OwnedHandle
- impl From‹PipeWriter› for OwnedHandle
- impl From‹PipeReader› for Stdio
- impl From‹PipeWriter› for Stdio
- impl From‹PipeReader› for OwnedFd
- impl From‹PipeWriter› for OwnedFd
- Box‹MaybeUninit‹T››::write
- impl TryFrom‹Vec‹u8›› for String
- ‹*const T›::offset_from_unsigned
- ‹*const T›::byte_offset_from_unsigned
- ‹*mut T›::offset_from_unsigned
- ‹*mut T›::byte_offset_from_unsigned
- NonNull::offset_from_unsigned
- NonNull::byte_offset_from_unsigned
- ‹uN›::cast_signed
- NonZero::‹uN›::cast_signed.
- ‹iN›::cast_unsigned.
- NonZero::‹iN›::cast_unsigned.
- ‹uN›::is_multiple_of
- ‹uN›::unbounded_shl
- ‹uN›::unbounded_shr
- ‹iN›::unbounded_shl
- ‹iN›::unbounded_shr
- ‹iN›::midpoint
- ‹str›::from_utf8
- ‹str›::from_utf8_mut
- ‹str›::from_utf8_unchecked
- ‹str›::from_utf8_unchecked_mut
- Признак "const" применён в функциях:
- core::str::from_utf8_mut
- ‹[T]›::copy_from_slice
- SocketAddr::set_ip
- SocketAddr::set_port,
- SocketAddrV4::set_ip
- SocketAddrV4::set_port,
- SocketAddrV6::set_ip
- SocketAddrV6::set_port
- SocketAddrV6::set_flowinfo
- SocketAddrV6::set_scope_id
- char::is_digit
- char::is_whitespace
- ‹[url=T;]N::as_flattened
- ‹[url=T;]N::as_flattened_mut
- String::into_bytes
- String::as_str
- String::capacity
- String::as_bytes
- String::len
- String::is_empty
- String::as_mut_str
- String::as_mut_vec
- Vec::as_ptr
- Vec::as_slice
- Vec::capacity
- Vec::len
- Vec::is_empty
- Vec::as_mut_slice
- Vec::as_mut_ptr
- Удалён второй уровень поддержки для целевой платформы i586-pc-windows-msvc. Рекомендуется использовать платформу i686-pc-windows-msvc, которая отличается поддержкой инструкций SSE2. Платформа i586-pc-windows-msvc потеряла смысл, так как для Windows 10 необходима поддержка SSE2, а более ранние выпуски Windows в Rust не поддерживаются.
Источник: https://www.opennet.ru/opennews/art.shtml?num=63242
(opennet.ru, основная лента)