TGViewer
Блог* Блог* @dereference_pointer_there · 1.98K subscribers
Post #1367 575
warning: unreachable pattern
--> src/main.rs:10:19
|
10 | $($prefix => (),)*
| ^^^^^^^
...
22 | / prefixes!(match s {
23 | | "foo".. => s.to_string(),
24 | | "foo".. => [s, s].concat(),
25 | | _ => String::new(),
26 | | })
| |______- in this macro invocation
|
note: the lint level is defined here
--> src/main.rs:8:20
|
8 | #[warn(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
...
22 | / prefixes!(match s {
23 | | "foo".. => s.to_string(),
24 | | "foo".. => [s, s].concat(),
25 | | _ => String::new(),
26 | | })
| |______- in this macro invocation
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

Окей, сообщение об ошибке могло бы быть и получше, но компилятор предупреждает нас о баге.

Можем ли мы улучшить результат? Безусловно: сейчас мы можем сматчить префикс, но не получаем остаток строки после него! Мы можем одновременно проверить, что строка начинается с указанного префикса, и получить остаток строки при помощи str::strip_prefix. Генерировать код при помощи такой функции несколько более хлопотно, поскольку при этом вместо match придётся писать связанные в цепочку if let, но задача решаема: для каждого префикса мы пытаемся отрезать префикс от строки, и, если это не выходит, пробуем следующий, а если не сработал ни один из префиксов, то исполняем ветку $catch_all:

macro_rules! cut_prefixes {
(match $value:ident {
$($prefix:literal ..= $rest:ident => $arm:expr,)*
_ => $catch_all:expr $(,)?
}) => {{
#[allow(dead_code)]
fn non_repeating() {
#[warn(unreachable_patterns)]
match "" {
$($prefix => (),)*
_ => (),
}
}
$(if let Some($rest) = $value.strip_prefix($prefix) {
$arm
} else)* {
$catch_all
}
}}
}

Напишем очередную малоосмысленную функцию, которая использует этот макрос:

fn use_cut_prefixes(s: &str) -> String {
cut_prefixes!(match s {
"foo"..=rest => rest.to_string(),
"bar"..=tail => [tail, tail].concat(),
_ => String::new(),
})
}

Функция main останется той же. Программа выдаёт:

"bar"
"foofoo"
""


То есть всё как и ожидалось. Защита от повторяющихся префиксов также работает.
doc.rust-lang.org str - Rust String slices.
More from @dereference_pointer_there
  1. Oct 7, 2026#meme про jab
  2. Oct 7, 2026"Famous car"
  3. Oct 7, 2026photo post
  4. Oct 7, 2026Во избежание оффтопа под постом о поиске работы срач дискуссию о криптовалютах обсуждайте…
  5. Oct 7, 2026Блог* pinned «Меня зовут Антон, и в настоящий момент я ищу работу. У меня 5 лет опыта в пр…
  6. Oct 7, 2026^Папищеки, обращаюсь к вам за помощью: поделитесь, пожалуйста, особенно если вы знаете, чт…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →