- PVSM.RU - https://www.pvsm.ru -
Команда Rust рада сообщить о выпуске новой версии, 1.42.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.
Если вы установили предыдущую версию Rust средствами rustup
, то для обновления до версии 1.42.0 вам достаточно выполнить следующую команду:
rustup update stable
Если у вас ещё не установлен rustup
, вы можете установить его [1] с соответствующей страницы нашего веб-сайта, а также посмотреть подробные примечания к выпуску [2] на GitHub.
Основными нововведениями Rust 1.42.0 являются более удобные сообщения о панике в случае вызова unwrap
, шаблоны срезов, объявление устаревшим Error::description
и многое другое. Смотрите подробности выпуска [2] для дополнительной информации.
Option
и Result
теперь включают полезные номера строкВ Rust 1.41.1 вызов unwrap()
для значения Option::None
порождало сообщение об ошибке примерно такого содержания:
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /.../src/libcore/macros/mod.rs:15:40
Аналогично, номера строк в сообщениях о панике, порождаемые вызовами unwrap_err
, expect
и expect_err
, как и соответствующими методами для типа Result
, тоже ссылались на внутренности core
.
В Rust 1.42.0 все эти восемь функций порождают сообщения о панике, которые включают такие номера строк, откуда они были вызваны. Новые сообщения выглядят примерно так:
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:2:5
Это означает, что ошибочный вызов unwrap
находился на строке 2 в файле src/main.rs
.
Это поведение стало возможным благодаря аннотации #[track_caller]
. Эта аннотация ещё не доступна в стабильной версии Rust, но если вы уже сейчас хотите использовать её в своём коде, вы можете отслеживать прогресс в этой задаче [3].
В Rust 1.26 мы стабилизировали так называемые "образцы по срезам [4]", позволяющие сопоставлять с образцами на срезах. Такие образцы выглядели примерно так:
fn foo(words: &[&str]) {
match words {
[] => println!("empty slice!"),
[one] => println!("one element: {:?}", one),
[one, two] => println!("two elements: {:?} {:?}", one, two),
_ => println!("I'm not sure how many elements!"),
}
}
Данный синтаксис позволял сопоставлять значения со срезами, но такие образцы были достаточно ограниченными. Вам приходилось выбирать точные размеры срезов, которые вы хотели поддерживать и вынуждены были предоставлять обработку случая по умолчанию для размеров срезов, которые вы поддерживать не хотели.
В Rust 1.42 у нас теперь есть расширенная поддержка сопоставления с частью среза [5]:
fn foo(words: &[&str]) {
match words {
["Hello", "World", "!", ..] => println!("Hello World!"),
["Foo", "Bar", ..] => println!("Baz"),
rest => println!("{:?}", rest),
}
}
Синтаксис ..
называется "остаточный образец" (rest pattern), потому что он сопоставляется с остаточной частью среза. Данный пример чуть выше использует остаточный образец в конце среза, но вы можете использовать такие образцы множеством других способов:
fn foo(words: &[&str]) {
match words {
// Игнорируем всё, за исключением последнего элемента, который должен быть "!".
[.., "!"] => println!("!!!"),
// `start` - это срез из всех элементов, кроме последнего, который должен быть "z".
[start @ .., "z"] => println!("starts with: {:?}", start),
// `end` - это срез из всех элементов, кроме первого, который должен быть "a".
["a", end @ ..] => println!("ends with: {:?}", end),
rest => println!("{:?}", rest),
}
}
Если вы заинтересовались и хотите узнать больше, мы опубликовали статью в блоге Inside Rust [6] с обсуждением этих изменений и разные улучшений сопоставления с образцом, которые мы могли бы включить в стабильную версию языка в будущем! Вы также можете прочитать больше об образцах по срезам в статье Томаса Хартманна [7].
matches!
[8]Этот релиз стабилизирует новый макрос, matches!
[9], который принимает выражение и образец, и возвращает true
, если образец сопоставим с выражением. Другими словами:
// Используя выражение match:
match self.partial_cmp(other) {
Some(Less) => true,
_ => false,
}
// Используя макрос `matches!`:
matches!(self.partial_cmp(other), Some(Less))
Вы можете также использовать образцы с |
и условные ограничения if
:
let foo = 'f';
assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));
let bar = Some(4);
assert!(matches!(bar, Some(x) if x > 2));
use proc_macro::TokenStream;
теперь работаетВ Rust 2018 мы избавились от необходимости в extern crate
[10]. Однако процедурные макросы оказались в какой-то степени особенными и, таким образом, когда вы создавали процедурный макрос, вам по-прежнему приходилось писать extern crate proc_macro;
.
В данном релизе, если вы используете Cargo, и если вы работаете с изданием 2018, вам больше не нужна эта строка; вы можете использовать use
подобно импорту из любого другого крейта [11]. Поскольку большинство проектов уже используют импорты, подобные use proc_macro::TokenStream;
, это изменение означает, что вы можете просто удалить строку extern crate proc_macro;
и ваш код останется рабочим. Изменение хоть и маленькое, но делает использование процедурных макросов более органичным по отношению к обычному коду.
iter::Empty<T>
теперь реализуют Send
и Sync
для любого T
. [12]Pin::{map_unchecked, map_unchecked_mut}
больше не требует возвращаемый тип, чтобы реализовать типаж Sized
. [5]io::Cursor
теперь реализует типажи PartialEq
и Eq
. [13]Layout::new
теперь const
. [14]CondVar::wait_while
[15] и CondVar::wait_timeout_while
[16]DebugMap::key
[17] и DebugMap::value
[18]ManuallyDrop::take
[19]ptr::slice_from_raw_parts_mut
[20] и ptr::slice_from_raw_parts
[21]Есть также другие изменения в релизе Rust 1.42.0: их полное описание смотрите в Rust [2] и Cargo [22].
В этом релизе есть два наиболее значимых момента по совместимости: устаревший функционал в стандартной библиотеке и понижение 32-битной платформы Apple до уровня 3.
Ошибки иногда совершаются. Error::description
теперь рассматривается как одна из таких ошибок. Проблема возникла с данной сигнатурой метода:
fn description(&self) -> &str
Поскольку метод description
возвращает &str
, теперь он совсем не так полезен, как мы ожидали этого раньше. То есть вам придётся возвратить содержимое значения Error
буквально; если вы хотели, скажем, использовать форматирование для более удобного и дружественного к пользователю описания ошибки, это оказывалось невозможно: вам нужно было вернуть String
. Вместо этого, современная практика программирования на языке Rust предполагает, что типы ошибок должны реализовывать типажи Display
/Debug
, чтобы предоставить возможность получения описания ошибки.
Этот API существовал начиная с Rust 1.0. Мы работали в этом направлении достаточно продолжительное время: ещё в Rust 1.27, мы объявили этот метод "немного устаревшим" [23]. Что это означало на практике это то, что мы сделали для этой функции реализацию по умолчанию. Это в свою очередь означает, что пользователи больше не вынуждены реализовывать типаж Error
. В данном релизе мы на самом деле объявили его устаревшим [24], и предприняли некоторые шаги, чтобы ослабить значимость этого метода в документации типажа Error
. Однако мы вынуждены следовать нашему соглашению о стабилизации, то есть метод description
никогда не будет удалён, и объявить устаревшим — это наибольшее, что мы можем сделать в данных условиях.
Apple больше не поддерживает 32-битные системы, так что и мы тоже не хотим. Эта платформа была понижена до поддержки Уровня 3. Детальнее об этом читайте эту статью [25] вышедшую ещё в Январе, там изложены все подробности.
Множество людей собрались вместе, чтобы создать Rust 1.42.0. Мы не смогли бы сделать это без всех вас, спасибо [26]!
С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате [27] или же в аналогичном чате для новичковых вопросов [28].
Данную статью совместными усилиями перевели andreevlex [29], funkill [30], Hirrolot [31] и nlinker [32].
Автор: RustLangRu
Источник [33]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/349593
Ссылки в тексте:
[1] установить его: https://www.rust-lang.org/install.html
[2] подробные примечания к выпуску: https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1420-2020-03-12
[3] в этой задаче: https://github.com/rust-lang/rust/issues/47809
[4] образцы по срезам: https://blog.rust-lang.org/2018/05/10/Rust-1.26.html#basic-slice-patterns
[5] расширенная поддержка сопоставления с частью среза: https://github.com/rust-lang/rust/pull/67935/
[6] статью в блоге Inside Rust: https://blog.rust-lang.org/inside-rust/2020/03/04/recent-future-pattern-matching-improvements.html
[7] статье Томаса Хартманна: https://thomashartmann.dev/blog/feature(slice_patterns)/
[8] matches!
: https://doc.rust-lang.org/stable/std/macro.matches.html
[9] matches!
: https://doc.rust-lang.org/nightly/std/macro.matches.html
[10] избавились от необходимости в extern crate
: https://doc.rust-lang.org/stable/edition-guide/rust-2018/module-system/path-clarity.html#no-more-extern-crate
[11] и если вы работаете с изданием 2018, вам больше не нужна эта строка; вы можете использовать use
подобно импорту из любого другого крейта: https://github.com/rust-lang/rust/pull/67887/
[12] iter::Empty<T>
теперь реализуют Send
и Sync
для любого T
.: https://github.com/rust-lang/rust/pull/68348/
[13] io::Cursor
теперь реализует типажи PartialEq
и Eq
.: https://github.com/rust-lang/rust/pull/67233/
[14] Layout::new
теперь const
.: https://github.com/rust-lang/rust/pull/66254/
[15] CondVar::wait_while
: https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html#method.wait_while
[16] CondVar::wait_timeout_while
: https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html#method.wait_timeout_while
[17] DebugMap::key
: https://doc.rust-lang.org/stable/std/fmt/struct.DebugMap.html#method.key
[18] DebugMap::value
: https://doc.rust-lang.org/stable/std/fmt/struct.DebugMap.html#method.value
[19] ManuallyDrop::take
: https://doc.rust-lang.org/stable/std/mem/struct.ManuallyDrop.html#method.take
[20] ptr::slice_from_raw_parts_mut
: https://doc.rust-lang.org/stable/std/ptr/fn.slice_from_raw_parts_mut.html
[21] ptr::slice_from_raw_parts
: https://doc.rust-lang.org/stable/std/ptr/fn.slice_from_raw_parts.html
[22] Cargo: https://github.com/rust-lang/rust/pull/67131/
[23] объявили этот метод "немного устаревшим": https://github.com/rust-lang/rust/pull/50163
[24] мы на самом деле объявили его устаревшим: https://github.com/rust-lang/rust/pull/68122/
[25] эту статью: https://blog.rust-lang.org/2020/01/03/reducing-support-for-32-bit-apple-targets.html
[26] спасибо: https://thanks.rust-lang.org/rust/1.42.0/
[27] русскоязычном Телеграм-чате: https://t.me/rustlang_ru
[28] чате для новичковых вопросов: https://t.me/rust_beginners_ru
[29] andreevlex: https://habr.com/ru/users/andreevlex/
[30] funkill: https://habr.com/ru/users/funkill/
[31] Hirrolot: https://habr.com/ru/users/hirrolot/
[32] nlinker: https://habr.com/ru/users/nlinker/
[33] Источник: https://habr.com/ru/post/491956/?utm_source=habrahabr&utm_medium=rss&utm_campaign=491956
Нажмите здесь для печати.