Есть, однако ещё один аспект
А вот что делать с
В заключение мне хотелось бы рассмотреть ограничения продемонстрированных подходов:
* в силу принципа организации генерируемого кода (цепочка условий против набора веток в ванильном матче) этот код почти наверняка хуже оптимизируется компилятором
* из-за ограничений
* синтаксически макросы всегда требуют запятых в конце веток
* паттерн для отлова всех необработанных случаев может быть только
* вариант
1.
2. Сделать функцию с атрибутом
Как всегда, весь код в гисте.
P. S.: разумеется, ничто не мешает сделать похожие штуки для матчинга по суффиксам
match, который нельзя использовать внутри наших макросов: охранные выражения на ветках! Можем ли мы интегрировать их? В случае с prefixes — безусловно: наш макрос в итоге в конечном счёте разворачивается в те же охранные выражения, в которые несложно добавить ещё одно условие. Надо лишь учесть, что эта часть синтаксиса опциональна:macro_rules! prefixes {
(match $value:ident {
$($prefix:literal .. $(if $condition:expr)? => $arm:expr,)*
// это новое ^^^^^^^^^^^^^^^^^^^^^^
_ => $catch_all:expr $(,)?
}) => {{
/* функция для отлова одинаковых префиксов */
match $value {
$(x if x.starts_with($prefix) $(&& $condition)? => $arm,)*
// вставляем условие ^^^^^^^^^^^^^^^^^
// из if clause, если оно есть
_ => $catch_all,
}
}}
}
И да, если в use_prefixes добавить ветку с if clause, то оно будет работать — с вашего позволения, я это опущу.А вот что делать с
cut_prefixes? В идеале нам бы хотелось просто взять и добавить к if let булево условие, но соответствующий RFC даже не принят, так что придётся выкручиваться. Один из возможных путей — это использовать тот же подход, что и в use_prefixes: сделать фиктивный match и поместить всё в охранные выражения. Доставать префикс тогда придётся при помощи split_at:macro_rules! cut_prefixes {
(match $value:ident {
$($prefix:literal..=$rest:ident $(if $cond:expr)? => $arm:expr,)*
// новая часть ^^^^^^^^^^^^^^^^^
_ => $catch_all:expr $(,)?
}) => {{
/* проверочная функция, бла-бла */
match $value {
$(x if x.starts_with($prefix) $(&& $cond)? => {
let (_, $rest) = x.split_at($prefix.len());
$arm
},)*
_ => $catch_all,
}
}}
}
И оно даже работает!В заключение мне хотелось бы рассмотреть ограничения продемонстрированных подходов:
* в силу принципа организации генерируемого кода (цепочка условий против набора веток в ванильном матче) этот код почти наверняка хуже оптимизируется компилятором
* из-за ограничений
macro_rules! значение, по которому происходит разбор, не может быть выражением (expr), а лишь идентификатором* синтаксически макросы всегда требуют запятых в конце веток
match, даже не смотря на то, что они не опциональны в match в тех случаях, когда ветки обрамлены в фигурные скобки* паттерн для отлова всех необработанных случаев может быть только
_ вместо также произвольного идентификатора в match
* в охранных выражениях в cut_prefix нельзя использовать имя, привязываемое к остатку строки* вариант
cut_prefixes, поддерживающий охранные выражения, менее эффективен — в подобном самодельном cut_prefix остаётся путь исполнения, ведущий к панике, даже на уровне оптимизации -O3. Это можно решить двумя способами:1.
str::split_at_unchecked — но это требует unsafe и потому не будет работать в кодовых базах с #![forbid(unsafe_code)];2. Сделать функцию с атрибутом
#[doc[hidden)] со str::split_at_unchecked внутри, не пометив её unsafe, и вызывать её в генерируемом коде — но это грязный хак, который нарушает гарантии safe Rust.Как всегда, весь код в гисте.
P. S.: разумеется, ничто не мешает сделать похожие штуки для матчинга по суффиксам
GitHub
Tracking issue for eRFC 2497, "if- and while-let-chains, take 2" · Issue #53667 · rust-lang/rust
Note: This feature was stabilized in 1.88.0 but on edition 2024 only. If you are using 1.88.0+ and get an error that the feature is still unstable, please upgrade the edition. The error message is ...
#rust #gamedev
Широко известный в узких русско-расто-, расто-геймедево- и русско-расто-геймдево- кругах Андрей "@ozkriff" Лесников наконец-то завёл в Telegram свой блог: @ozkriff_games. Некоторые скажут, что для #blogrecommendation это рановато, с учётом того, что там пока лишь 3 сообщения, но как человек, знакомый с Андреем, я выдаю ему большой кредит доверия. Буду ждать крутых постов! ✊
P. S.: а ещё он работает в JetBrains
Широко известный в узких русско-расто-, расто-геймедево- и русско-расто-геймдево- кругах Андрей "@ozkriff" Лесников наконец-то завёл в Telegram свой блог: @ozkriff_games. Некоторые скажут, что для #blogrecommendation это рановато, с учётом того, что там пока лишь 3 сообщения, но как человек, знакомый с Андреем, я выдаю ему большой кредит доверия. Буду ждать крутых постов! ✊
P. S.: а ещё он работает в JetBrains
Блог*
Сколько вам лет?
(диапазон с включающей нижней и исключающей верхней границами)
(диапазон с включающей нижней и исключающей верхней границами)
Мне аж интересно стало. Кто эти двое с возрастом 60+?
Блог*
#prog #rust #моё В Rust есть такая удобная вещь, как сопоставление с образцом (pattern matching), и она работает в том числе и для строк. К сожалению, оно позволяет сопоставлять только строки целиком, но не по частям. В частности (no pun intended), match…
Обсуждал с Доге, что в Scala можно это сделать на кастомных экстракторах, а оказалось, это уже есть: https://t.iss.one/lilfunctor/209
Telegram
Lil Functor
Увидел в канале про Rust (кстати, рекомендую) пост о том, как сделать паттерн-матчинг строк с выделением их составных частей. Например, разматчить строку по известному префиксу: https://t.iss.one/dereference_pointer_there/1366
Задумался о том, как написать то…
Задумался о том, как написать то…
Блог*
Обсуждал с Доге, что в Scala можно это сделать на кастомных экстракторах, а оказалось, это уже есть: https://t.iss.one/lilfunctor/209
Лёгким росчерком клавиатуры @poslegm (автор @lilfunctor) привлёк внимание к моему каналу, из-за чего число подписчиков наконец перевалило за шесть сотен. Спасибо!
Forwarded from XYZ
Twitter-аккаунт Crazy Optical Illusions посвящён, как видно по названию, самым невероятным оптическим иллюзиям.
Но все они объединены интересной особенностью, о которой мы предлагаем вам догадаться самостоятельно.
Но все они объединены интересной особенностью, о которой мы предлагаем вам догадаться самостоятельно.
#prog #rust #rustlib #amazingopensource
lingua-rs — библиотека для распознавания языка, на котором написан текст.
В отличие от аналогов, она даёт большую точность за счёт:
1) статистических моделей с n-gram-ами при n = 5, что позволяет достаточно надёжно классифицировать даже короткие фразы;
2) набора правил, применяемых до применений статистического анализа, которые могут сократить круг потенциальных языков за счёт, например, обнаружения символов, уникальных для специфических языков.
lingua-rs — библиотека для распознавания языка, на котором написан текст.
В отличие от аналогов, она даёт большую точность за счёт:
1) статистических моделей с n-gram-ами при n = 5, что позволяет достаточно надёжно классифицировать даже короткие фразы;
2) набора правил, применяемых до применений статистического анализа, которые могут сократить круг потенциальных языков за счёт, например, обнаружения символов, уникальных для специфических языков.
GitHub
GitHub - pemistahl/lingua-rs: The most accurate natural language detection library for Rust, suitable for short text and mixed…
The most accurate natural language detection library for Rust, suitable for short text and mixed-language text - pemistahl/lingua-rs
Forwarded from Архонт щітпосту | #укртґ
Кстати, остался последний месяц 2020. Предлагаю собрать аптечки, патроны и броню, потому что боссфайт уже близко
#записки
#записки