Команда Rust рада сообщить о выпуске новой версии — 1.53.0. Rust — это язык программирования, позволяющий каждому создавать надёжное и эффективное программное обеспечение.
Если вы установили предыдущую версию Rust средствами rustup
, то для обновления до версии 1.53.0 вам достаточно выполнить следующую команду:
rustup update stable
Если у вас ещё не установлен rustup
, вы можете установить его с соответствующей страницы нашего веб-сайта, а также посмотреть подробные примечания к выпуску на GitHub.
Что было стабилизировано в 1.53.0
Этот выпуск содержит несколько новых возможностей языка и ещё больше — стандартной библиотеки, включая долгожданную реализацию IntoIterator
для массивов. Смотрите подробные примечания к выпуску, чтобы узнать о других изменениях, не представленных в данном анонсе.
IntoIterator
для массивов
Это первый выпуск Rust, в котором массивы реализуют типаж IntoIterator
. Теперь вы можете итерироваться в массиве по значению:
for i in [1, 2, 3] {
..
}
Раньше это было возможно только по ссылке, с помощью &[1, 2, 3]
или [1, 2, 3].iter()
.
Аналогично вы теперь можете передать массив в методы, ожидающие T: IntoIterator
:
let set = BTreeSet::from_iter([1, 2, 3]);
for (a, b) in some_iterator.chain([1]).zip([1, 2, 3]) {
..
}
Это не было реализовано ранее из-за проблем с совместимостью. IntoIterator
всегда реализуется для ссылок на массивы — и в предыдущих выпусках array.into_iter()
компилировался, преобразовываясь в (&array).into_iter()
.
Начиная с этого выпуска, массивы реализуют IntoIterator
с небольшими оговорками для устранения несовместимости кода. Компилятор, как и прежде, преобразовывает array.into_iter()
в (&array).into_iter()
, как если бы реализации типажа ещё не было. Это касается только синтаксиса вызова метода .into_iter()
и не затрагивает, например, for e in [1, 2, 3]
, iter.zip([1, 2, 3])
или IntoIterator::into_iter([1, 2, 3])
, которые прекрасно компилируются.
Так как особый случай .into_iter()
необходим только для предотвращения поломки существующего кода, он будет удалён в новой редакции Rust 2021, которая выйдет позже в этом году. Если хотите узнать больше — следите за анонсами редакции.
"Или" в шаблонах
Синтаксис шаблонов был расширен поддержкой |
, вложенного в шаблон где угодно. Это позволяет писать Some(1 | 2)
вместо Some(1) | Some(2)
.
match result {
Ok(Some(1 | 2)) => { .. }
Err(MyError { kind: FileNotFound | PermissionDenied, .. }) => { .. }
_ => { .. }
}
Unicode-идентификаторы
Теперь идентификаторы могут содержать не-ASCII символы. Можно использовать все действительные идентификаторы символов Unicode, определённые в UAX #31. Туда включены символы из многих разных языков и письменностей — но не эмодзи.
Например:
const BLAHAJ: &str = "";
struct ? {
??: String,
}
let ? = 1;
Компилятор предупредит о потенциальной путанице с участием разных символов. Например, при использовании идентификаторов, которые выглядят очень похоже, мы получим предупреждение:
warning: identifier pair considered confusable between `s` and `s`
Поддержка имени HEAD-ветки в Cargo
Cargo больше не предполагает, что HEAD
-ветка в git-репозитории называется master
. А следовательно, вам не надо указывать branch = "main"
для зависимостей из git-репозиториев, в которых ветка по умолчанию main
.
Инкрементальная компиляция до сих пор отключена по умолчанию
Как ранее говорилось в анонсе 1.52.1, инкрементальная компиляция была отключена для стабильных выпусков Rust. Функциональность остаётся доступной в каналах beta и nightly. Метод включения инкрементальной компиляции в 1.53.0 не изменился с 1.52.1.
Стабилизированные API
Следующие методы и реализации типажей были стабилизированы:
array::from_ref
array::from_mut
AtomicBool::fetch_update
AtomicPtr::fetch_update
BTreeSet::retain
BTreeMap::retain
BufReader::seek_relative
cmp::min_by
cmp::min_by_key
cmp::max_by
cmp::max_by_key
DebugStruct::finish_non_exhaustive
Duration::ZERO
Duration::MAX
Duration::is_zero
Duration::saturating_add
Duration::saturating_sub
Duration::saturating_mul
f32::is_subnormal
f64::is_subnormal
IntoIterator for array
{integer}::BITS
io::Error::Unsupported
NonZero*::leading_zeros
NonZero*::trailing_zeros
Option::insert
Ordering::is_eq
Ordering::is_ne
Ordering::is_lt
Ordering::is_gt
Ordering::is_le
Ordering::is_ge
OsStr::make_ascii_lowercase
OsStr::make_ascii_uppercase
OsStr::to_ascii_lowercase
OsStr::to_ascii_uppercase
OsStr::is_ascii
OsStr::eq_ignore_ascii_case
Peekable::peek_mut
Rc::increment_strong_count
Rc::decrement_strong_count
slice::IterMut::as_slice
AsRef<[T]> for slice::IterMut
impl SliceIndex for (Bound<usize>, Bound<usize>)
Vec::extend_from_within
Другие изменения
Синтаксис, пакетный менеджер Cargo и анализатор Clippy также претерпели некоторые изменения.
Участники 1.53.0
Множество людей собрались вместе, чтобы создать Rust 1.53.0. Мы не смогли бы сделать это без всех вас. Спасибо!
От переводчиков
С любыми вопросами по языку Rust вам смогут помочь в русскоязычном Телеграм-чате или же в аналогичном чате для новичковых вопросов. Если у вас есть вопросы по переводам или хотите помогать с ними, то обращайтесь в чат переводчиков.
Также можете поддержать нас на OpenCollective.
Данную статью совместными усилиями перевели TelegaOvoshey, blandger, Belanchuk и funkill.
nlinker
Кому интересно, мнения в соответствующем RFC разделились примерно поровну:
https://github.com/rust-lang/rfcs/pull/2457
myxo
А как с этим вообще предполагается работать, если нет символов на клавиатуре? Ctrl-C, Ctrl-V?
ilammy
Обычно у людей, которым необходимы нестандартные символы, настроены всякие автозамены аккордов. Набираешь
\
a
=>?
,|
N
|
=>?
, и т. д.myxo
я больше про кейс работы с чужим кодом
ilammy
Что вы тогда делаете в коде, где нужны специальные символы, если о них не знаете?
Одно дело использовать символы за пределами ASCII, потому что так удобнее для предметной области — и другое дело, когда это стилистический выбор. В первом случае вы как-нибудь решите для себя вопрос их набора, потому что польза перевешивает неудобства. Второй случай — это только вопрос конвенции.
Можно же научить линтер давать по шапке за идентификаторы
lIllI1l
иI11lIl1
. Точно так же можно гонять и за несогласованные non-ASCII идентификаторы. Но это решает каждый отдельный проект для себя самостоятельно, а не разработчики компилятора за всех.myxo
Не, то что в принципе возможно — это прекрасно. То, что можно выключать — тоже хорошо.
Другое дело, что эта фича (насколько я сейчас вижу) нужна очень ограниченному кругу разработчиков, а подавляющему большинству это только вредит, то есть во всех проектах где я захочу работать, эту фичу нужно будет явно выключать. Вот нужно мне будет посмотреть код китайских товарищей, а там иероглифы. И… все.
Мне это кажется странным. Логичнее было бы сделать off by default.
DarkEld3r
Если вместо иероглифов будет транслит — станет легче? (:
myxo
Ну вообще да, легче. Как минимум я смогу с клавиатуры набрать переменные в коде или дебаггере. Да и к тому же я не думаю что смогу с ходу отличить и держать в памяти два разных иероглифа или слова арабской вязи. С латиницей, пусть и белебирдой, будет чуть проще.
n3kitOzz
обфускация хорошая получается))
а вообще да, должны быть нормальные стандарты.
Revertis
Просто отрефакторить переименовав и всё. Пусть не вы**ываются.
shamilsan
Как по мне, это одно из самых сомнительных нововведений. Я сомневаюсь, что эта фича найдёт массовое применение. По крайней мере, надеюсь на это.
yar3333
В C# поддерживаются национальные символы в идентификаторах. В норме никто их не использует. Но раз в год и палка стреляет :))
Teplo_Kota
Если речь про unicode в именах, то я только за, причём из опыта. Русские парни, на С++98, писали программу, не будучи большими спецами в предметной области. Поэтому они пользовались учебниками, написанными на русском. И помощью профессора, который знал два иностранных языка: французкий и немецкий. Объекты из предметной области регулярно попадают в код в виде переменных. И вот…
Нет, программист ещё сможет перевести «соосность опорной втулки» или «правило подчинения приданного отделения взводу» на английский. Но вот потом обратно полученный перл уже никто другой не переведёт. А значит, не сможет найти в учебнике, что это, и не сможет спросить профессора. Регулярно возникал хаос на эту тему. А что делать?
Пробовали писать транслитом. Получалось хреново. Во-первых, как оказалось, бывает транслитная дислексия. Молодой джун, в остальном весьма справный, не способен прочитать длинный транслит пока медленно, по буквам, не перепишет его нашими буквами. Пара сотрудников постарше регулярно забывали правила транслита, сочиняли нечитаему хрень. Написал им программу, делающую транслит туда-сюда. Но теперь, чтобы прочитать название переменной, трём людям нужно его скопировать и вставить. Во вторых, от транслит у автокомплита в IDE крыша ехала, но как и почему не помню.
В итоге, сначала со злости, а потом на полном серьёзе стали использовать такую систему: любая мало-мальски сложная в переводе переменная называется stvar9475894253, где stvar означает strange variable, а 9475894253 — случайное число, для уникальности имени. И в комментарии написано на русском, что это значит квалитет посадочного места подшипника коленвала. Для долгоживущих переменных с проектом идёт файлик, где эти переменные перечислены, и на русском написано, что они значат. Люди на полном серьёзе всем коллективным бессознательным определили, что так проще, чем возиться с транслитом или переводами.
Уже после, впервые столкнувшись с языками, где есть юникодные имена, я сто раз подумал, как было бы охрененно круто иметь их в том старом проекте. Но при этом они мне больше никогда не понадобились: больше нигде предметная область не просачивалась так активно в код.
insecto
Отличная стратегия, я бы тоже так делал. Я и сейчас так с ошибками делаю, если у меня в рантайме проверяется инвариант, я делаю throw new Error ('Error 123123123') где число случайное бит хотя бы на 32. Тогда если оно вдруг почему-то стрельнет в рантайме (а не должно!), то во-первых никакая чувствительная инфа не утечёт ни в крешлог ни не дай бог пользователю. Плюс, если кто-то репортит ошибку, то сразу можно искать по коду и понимать где бахнуло. Короче, сплошной профит, всем рекомендую.
Teplo_Kota
Тут важно подумать, какой уровень поддержки ваша компания обещает пользователям. Если отвечают в течении часа 24/7 то это одно. А вот если нет, то рассмотрим такую ситуацию: Пользователю выпадает ошибка номер 0xBABADEDA. А он сам опытный пользователь, может даже админ. И на машине много чего наворочено. Лезет гуглить номер ошибки — а в Интернете нет ничего. Пишет в поддержку, и через 3 дня получает совет перезагрузиться. Пишет опять, ругается, и наконец ему сообщают ещё через 3 дня что эта ошибка «не могу инициализировать видеокарту». Пользователь вспоминает, что у него дрова подшаманеные, переустанавливает их, и всё работает. Вот только пользователь ощущает, что с ним обошлись, как с полным идиотом. И неделю работа стояла ради двухминутной починки.
С таким подходом к ошибке нужно тщательно поддерживать публичный список кодов ошибок. Следить, чтобы в нём было всё, что нужно. И не было того, что не нужно. Microsoft вот не справилась. Пользователи регулярно жалуются об ошибках с туманными кодами, которые не гуглятся, беспомощной техподдержке и тому, что в итоге нужно было переустановить VCRedist2015. А ещё есть Adobe, у которого публичного списка вообще нет. И техподдержка морозится и отказывается внятно помочь в хоть сколько-то сложном случае. В результате часто вижу заявления типа «Единственный способ починить Adobe — форматнуть весь комп.»