TGViewer
Блог* Блог* @dereference_pointer_there · 1.98K subscribers
Post #1411 646
#prog #rust #моё

Вы что, правда думали, что за всеми празднествами я оставлю вас без поста? Не скрою, идея заманчивая, но я решил ей не поддаваться... Хотя к тому моменту, как я закончу писать этот пост, уже наверняка наступит 6 декабря... Впрочем, достаточно прелюдий — переходим к постановке задачи!

Иногда нам требуется сопоставить значение с одной из строк... Но при этом игнорируя регистр символов. В общем случае это довольно сложная задача, и даже не из-за зависимости от локали, а просто от сложности правил перевода символов из одного регистра в другой. Пока что забьём на это и будем рассматривать только ASCII-строки. Что нам требуется? Чтобы:
а) чтобы можно было сопоставить (ASCII) строку, невзирая на её регистр;
б) чтобы нас предупреждал компилятор о перекрывающихся паттернах (а вот это уже интересно — компилятор требует точного совпадения паттернов для проверки);
в) чтобы по возможности сохранить возможности, предоставляемые match.

Итак, как нам проверить, что строки неодинаковы с точностью до регистра? В принципе, можно сделать уже известным способом const assert, используя соответствующие const fn, но так как я человек ленивый, я пойду по лёгкому пути: я проверю, что все паттерны на самом деле в нижнем регистре, а проверить их уникальность оставлю компилятору.

Итак, переходим к подзадаче: убедиться, что строка состоит из символов ASCII, но в нижнем регистре, на этапе компиляции. Правда, так как мы хотим использовать в паттернах не только буквы, но и, скажем, цифры, правильнее сказать "из символов ASCII не в верхнем регистре". Для решения части "на этапе компиляции" воспользуемся уже знакомым трюком, который я тут вроде уже показывал: заведём новую константу типа [(); 1], а в качестве значения ей присвоим [(); condtion as _], где condition — условие, которое нам нужно проверить. Если condition вычисляется в true (и вычисляется на этапе компиляции в принципе), то as _ приводит булево значение к 1usize, получая выражение [(); 1], соответствующее типу. В противном случае false приводится к 0 и выражение принимает вид [(); 0], вызывая ошибку компиляции из-за несовпадения типов. Теперь всё, что нам остаётся для решения это подзадачи — написать функцию, которую можно вызвать на этапе компиляции и которая проверяет указанное выше условие. Написать такую функцию несколько неудобно из-за ограничений const fn (в частности, мы не можем использовать итераторы), но вполне возможно:

const fn is_ascii_lowercase(s: &str) -> bool {
let s = s.as_bytes();
let len = s.len();
let mut i = 0;
while i < len {
if !s[i].is_ascii() || s[i].is_ascii_uppercase() {
return false;
}
i += 1;
}
true
}

Ладно, а как нам проверить, что несколько строк записаны в ASCII lowercase? Ну как-как, принимаем список и проходимся о нему:

const fn are_all_ascii_lowercase(ss: &[&str]) -> bool {
let len = ss.len();
let mut i = 0;
while i < len {
if !is_ascii_lowercase(&ss[i]) {
return false;
}
i += 1;
}
true
}

Окей, с этой подзадачей мы разобрались. Как нам теперь убедиться, что все строки разные? А эту задачу мы уже решали: генерируем функцию, которая разбирает строку, и подсовываем в match наши строки — и компилятор всё прекрасно проверяет за нас!
Telegram Блог* #prog #rust #моё Как сравнить в Rust две строки, игнорируя регистр символов? Строго говоря, используя лишь стандартную библиотеку — никак, поскольку перевод из одного регистра в другой зависит от локали, но давайте пока проигнорируем эту деталь и притворимся…
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 →