Хабрахабр

Выпуск Rust 1.35.0

Представляю Вашему вниманию перевод публикации о новой версии всеми любимого языка программирования Rust.

35. Команда по разработке языка программирования Rust рада анонсировать новую версию, 1. Rust — это язык программирования, позволяющий каждому разрабатывать надёжное и быстрое ПО. 0.

Если предыдущую версию Rust Вы установили средствами rustup, получение текущей версии не составит особого труда:

$ rustup update stable

Детальный обзор данного релиза доступен на GitHub. Если у Вас всё ещё нет rustup, Вы можете получить его с соответствующей страницы на нашем сайте.

Главными новшествами этого релиза можно назвать реализации трейтов FnOnce, FnMut и Fn на структурах Box<dyn FnOnce>, Box<dyn FnMut> и Box<dyn Fn> соответственно.

Макрос dbg!, введённый в Rust 1. А также встраиваемые функции (closures) могут быть сконвертированы в небезопасные указатели на функции. 0, теперь может быть вызван без указания аргументов. 32.

Ниже представлены наиболее существенные, но доступен и детальный разбор оных. Более того, данный релиз внёс множество стабилизаций стандартной библиотеки.

35. В Rust 1. 0, трейты FnOnce, FnMut и Fn реализованы на Box<dyn FnOnce>, Box<dyn FnMut> и Box<dyn Fn> соответственно.

Это также мешало передачи инкапсулированных в Box функций коду, ожидавшему реализатора трейта Fn (предлагалось создавать временные встраиваемые функции). В прошлом, если Вы желали вызвать функцию, инкапсулированную в Box, Вам необходимо было воспользоваться FnBox, так как объекты Box<dyn FnOnce> и подобные не реализовывали соответствующие трейты Fn*.

Этот недостаток был устранён с введением unsized_locals. Это было вызвано неспобностью компилятора обнаружать подобные реализации.

Например, приведённый ниже код компилируется без ошибок: Однако теперь Вы можете использовать инкапсулированные в Box функции даже в тех местах, которые ожидают реализацию функционального трейта.

fn foo(x: Box<dyn Fn(u8) -> u8>) -> Vec<u8> { vec![1, 2, 3, 4].into_iter().map(x).collect()
}

Объекты Box<dyn FnOnce> могут быть вызваны без лишней возни:

fn foo(x: Box<dyn FnOnce()>) { x()
}

19. Со времен Rust 1. Например, вы могли написать: 0 стало возможным конвертирование встраиваемых функций, не захватывавших среду в указатели на функции.

fn twice(x: u8, f: fn(u8) -> u8) -> u8 { f(f(x))
} fn main() { assert_eq!(42, twice(0, |x| x + 21));
}

Данный релиз привнёс описанные выше изменения: Но к сожалению, данная возможность не была расширена до небезопасных указателей на функции.

/// Безопасные инварианты, переданные в `unsafe fn`.
unsafe fn call_unsafe_fn_ptr(f: unsafe fn()) { f()
} fn main() ); }
}

32. Вследствие обилия вызовов println! в качестве колхозных дебаггеров, в Rust 1. Напомним, что данный макрос позволяет быстро запечатлить результат некого выражения с контекстом: 0 был представлен макрос dbg!.

fn main() { let mut x = 0; if dbg!(x == 1) { x += 1; } dbg!(x);
}

Приведённые выше строки кода напечатают в терминал результат выражения x == 1 и x соответственно:

[src/main.rs:4] x == 1 = false
[src/main.rs:8] x = 0

Это может быть крайне полезно для обнаружения выбранных программных веток: Как было сказано в предыдущей секции, где может быть вызвана функция высшего порядка call_unsafe_fn_ptr, dbg!() также подлежит вызову без указания аргументов.

fn main() { let condition = true; if condition { dbg!(); // [src/main.rs:5] }
}

35. В Rust 1. В дополнении к этому, были внесены некоторые реализации, о которых Вы можете прочесть тут. 0, множество компонентов стандартной библиотеки были стабилизированы.

Копирование знака числа с плавающей точкой в другое число

С данным релизом, новые методы copysign были добавлены в примитивы с плавающей точкой (конкретнее, f32 и f64):

Как можно было предположить из названия методов, Вы можете использовать их для копирования знака одного числа в другое:

fn main() { assert_eq!(3.5_f32.copysign(-0.42), -3.5);
}

Проверка того, содержит ли Range определённое значение

35. Rust 1. 0 приобрёл парочку новых методов на структурах Range*:

Например, Вы можете написать: С помощью данных методов, Вы можете с лёгкостью проверить, находится ли определённое значение в диапазоне.

fn main() { if (0..=10).contains(&5) { println!("5 находится в диапазоне [0; 10]."); }
}

Перевести (map) и разбить (split) заимствованный RefCell

35. С приходом Rust 1. 0, Вы можете перевести и разбить заимствованное значение RefCell на множество заимствованных значений на разные компоненты заимствованных данных:

Переставить значение RefCell через встраиваемую функцию

Этот релиз представляет удобный метод replace_with, объявленный на структуре RefCell:

Хешировать указатель или ссылку по адресу

Использование ptr::hash способно предотвратить хеширование указываемого или ссылаемого значения вместо самого адреса. Данный релиз представляет функцию ptr::hash, принимающую сырой указатель для хеширования.

Копирование контента Option<&T>

0. С началом Rust 1. Однако клонирование иногда может быть дорогостоящей операцией, а методы opt.cloned() не описывали никаких подсказок. 0, методы Option::cloned на Option<&T> и Option<&mut T> позволяли клонировать содержание в случае его присутствия (Some(_)).

Этот релиз внёс:

Однако описанный выше метод запрашивает условия T: Copy, невыполнение которого вызвет ошибку компиляции. Функциональность opt.copied() такая же, как и opt.cloned().

Оно срабатывает в тех случаях, когда обобщённая функция запрашивает выполнения условия T: Drop: Clippy, инструмент, отлавливающий часто встречаемые несовершенности для повышения качества кода, обзавёлся drop_bounds.

fn foo<T: Drop>(x: T) {}

Более того, T: Drop не покрывает типы, подобные String, не имеющие наглядного поведения деструктора, а скорее результат встраиваемых типов (как Vec<u8>). Это часто является ошибкой, так как примитивы не реализуют Drop.

В дополнении к drop_bounds, данный релиз разделяет redundant_closure в redundant_closure и redundant_closure_for_method_calls.

Прочесть детальный релиз Clippy можно тут.

Детальное описание изменений Cargo доступно здесь.

35. Множество людей собрались вместе чтобы создать Rust 1. Мы не смогли бы сделать это без всех Вас, спасибо! 0.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть