Добавлены новые возможности для константных контекстов
Ссылки на статические переменные -> Теперь константы могу ссылаться на неизменяемые статические переменный, что делает код более гибкими и уменьшает его количество ограничений при написании константных выражений.
static S: i32 = 25;
const C: &i32 = &S;
fn main() { println!("Значение константы: {}", C); }
но не будет работать так
static mut S: i32 =0;
const C: &i32 = &S
так как нельзя ссылаться на мутабельную переменную в константе
Появилась возможность использовать мутабельные ссылки и указатели в контексте констант, что значительно расширяет возможности работы с const fn
и другими вычислениями на этапе компиляции.
Однако важно понимать, что эти мутабельные ссылки и указатели могут использоваться только внутри вычислений констант, но не могут быть частью конечного значения константы.
const fn inc(x: &mut i32) {
*x += 1;
}
const fn make_mutable_reference() -> i32 {
let mut val = 41;
inc(&mut val);
val
}
const C: i32 = make_mutable_reference();
fn main() {
println!("Значение константы C: {}", C);
}
не нужно путать с примеров выше!!!
Выражение, содержащее мутабельные ссылки, может быть вычислено на этапе компиляции, но нельзя использовать мутабельную ссылку как часть конечного значения константы:
const C: &mut i32 = &mut 4; // Ошибка: mutable references are not allowed in the final value of constants
мутабельный указатель в константном контексте
use std::cell::UnsafeCell;
const fn modify_with_raw_pointer() -> i32 {
let c = UnsafeCell::new(41);
unsafe { *c.get() += 1 };
c.into_inner()
}
const C: i32 = modify_with_raw_pointer();
fn main() {
println!("Значение константы C: {}", C);
}
Но это все еще с ограничениями для обеспечения безопастности типов и предотвращения небезопасных операций.
Стабилизация новых методов для коллекций
Option::unwrap_unchecked
Option::replace
расширяют возможности обработки значений, что делает код более выразительным и удобным.
Изменения касается стабилизации методов для работы с сырыми указателями и мутабельными ячейками, что указывает на улучшения для низкоуровневых операций и работы с памятью.
Новые ошибки в ErrorKind
улучшают поддержку работы с файловыми системами, что делает работу с низкоуровневыми операциями более безопасной и предсказуемой.
Оптимизированна работа
ptr::replace
ptr::slice_from_raw_parts_mut
для работы с сырыми указателями для модификации данных в массивах или срезах без необходимости копировать их.
Исправлены
slice::from_mut
slice::from_raw_parts_mut
для работы с мутабельными срезами, позволяющие изменять данные в массивах или срезах без необходимости копировать их.
//выглядит теперь это так
use std::ptr;
fn main() {
let mut arr = [1, 2, 3, 4, 5];
let ptr = arr.as_mut_ptr();
unsafe {
let slice = std::slice::from_raw_parts_mut(ptr, arr.len());
slice[0] = 10;
slice[4] = 20;
println!("Изменённый массив: {:?}", arr);
// Выведет: [10, 2, 3, 4, 20]
}
}
Обратите внимание что этот код находится внутри небезопастного блока unsafe
,по скольку работа с сырыми указателями требует явного размешения на безопастный код.
Эти методы позволяют безопасно получать мутабельные ссылки на первый и последний элементы среза или массива. пример как теперь это работает
fn main() {
let mut arr = [1, 2, 3, 4, 5];
if let Some(first) = arr.first_mut() {
*first = 10;
}
println!("Изменённый массив: {:?}", arr);
// Выведет: [10, 2, 3, 4, 5]
}
Option::get_or_insert_default
Теперь позволяет вставить значение по умолчанию в Option
, если оно ещё не инициализировано (то есть если Option
является None
).
Эта функция полезна, например, при работе с кэшами, коллекциями или в ситуациях, где вы хотите гарантировать, что значение существует, и при необходимости инициализировать его значением по умолчанию.
use std::collections::HashMap;
fn main() {
let mut cache: Option<HashMap<String, i32>> = None;
cache.get_or_insert_default().insert("apple".to_string(), 5);
cache.get_or_insert_default().insert("banana".to_string(), 7);
if let Some(map) = cache {
println!("Кэш: {:?}", map);
}
}
//пример работы с вектором
fn main() {
let mut nums: Option<Vec<i32>> = None;
nums.get_or_insert_default().push(10);
nums.get_or_insert_default().push(20);
if let Some(vec) = nums {
println!("Вектор: {:?}", vec);
}
}
Методы для работы с числами и строками:
char::MIN:
Минимальный символ, доступный в языке.
{float}::classify
{float}::is_finite
{float}::is_infinite
и другие:
Стабилизированные методы для работы с числами с плавающей точкой, включая проверку на бесконечность, нормальность и другие атрибуты.
str::as_mut_ptr str::from_utf8_unchecked_mut
Методы для работы с мутабельными строками, которые могут быть полезны в высокопроизводительных приложениях, где требуется манипуляция строками без излишних проверок.
как теперь это работает в 1.83.0
f32::classify и f64::classify`
fn main() {
let numbers = [3.14, 0.0, f32::INFINITY, f32::NEG_INFINITY, f32::NAN];
for &num in &numbers {
match num.classify() {
std::num::FpCategory::Normal => println!("Число {:?} нормальное", num),
std::num::FpCategory::Subnormal => println!("Число {:?} поднормальное", num),
std::num::FpCategory::Zero => println!("Число {:?} равно нулю", num),
std::num::FpCategory::Infinite => println!("Число {:?} бесконечность", num),
std::num::FpCategory::Nan => println!("Число {:?} NaN", num),
}
}
}
//Число 3.14 нормальное
//Число 0.0 равно нулю
//Число inf бесконечность
//Число -inf бесконечность
//Число NaN NaN
f32::is_finite и f64::is_finite`
Метод is_finite
проверяет, является ли число конечным (не бесконечностью или NaN
).
fn main() {
let numbers = [3.14, 0.0, f32::INFINITY, f32::NEG_INFINITY, f32::NAN];
for &num in &numbers {
if num.is_finite() {
println!("Число {:?} конечное", num);
} else {
println!("Число {:?} не конечное", num);
}
}
}
//Число 3.14 конечное
//Число 0.0 конечное
//Число inf не конечное
//Число -inf не конечное
//Число NaN не конечное
f32::is_infinite и f64::is_infinite`
Метод is_infinite
проверяет, является ли число бесконечностью (положительной или отрицательной).
fn main() {
let numbers = [3.14, 0.0, f32::INFINITY, f32::NEG_INFINITY, f32::NAN];
for &num in &numbers {
if num.is_infinite() {
println!("Число {:?} бесконечность", num);
} else {
println!("Число {:?} не бесконечность", num);
}
}
}
//Число 3.14 не бесконечность
//Число 0.0 не бесконечность
//Число inf бесконечность
//Число -inf бесконечность
//Число NaN не бесконечность