#rust #macros
#Ржавчина #сопоставление с образцом
Вопрос:
Я пишу игрушечный язык программирования на Rust. Я создал прототип логики синтаксического анализатора на Ruby:
def rd_tree(chars)
loop do
case c = chars.next
when /s/
# whitespace stuff
when "("
# open paren stuff
when ")"
# close paren stuff
else
# default stuff
end
end
end
И теперь я конвертирую его в Rust:
fn rd_tree(chars: std::str::Chars) {
while let Some(c) = chars.next() {
if c.is_whitespace() {
// whitespace stuff
} else if c == '(' {
// open paren stuff
} else if c == ')' {
// close paren stuff
} else {
// default stuff
}
}
}
Я прибегнул к использованию цепочки if, else-if, потому что, насколько я могу судить, функция сопоставления Rust ограничена деструктурированием, перечислениями и шаблонами типов. Есть ли способ сопоставления регулярных выражений или логических функций? Если нет, есть ли здесь более идиоматичный шаблон, чем if, else-if? Я ожидаю, что в будущем у логики будет больше ветвей, и я хочу, чтобы она оставалась аккуратной.
Ответ №1:
Пока нет. match
Шаблоны должны состоять из элементов, которые могут быть статически проверены компилятором.
Тем не менее, вы можете использовать защиту от совпадений:
fn rd_tree(chars: std::str::Chars) {
while let Some(c) = chars.next() {
match c {
c if c.is_whitespace() => {}
'(' => {}
')' => {}
_ => {}
}
}
}
Защита от совпадения позволяет вам запускать функцию против любого совпадающего шаблона.
В будущем постоянная оценка может быть улучшена, чтобы позволить вызывать функции вместо шаблона:
#[derive(PartialEq, Eq)]
struct Foo {
f: usize,
g: usize,
}
impl Foo {
const fn repeated(x: usize) -> Self {
Foo { f: x, g: x }
}
}
fn main() {
let f = Foo { f: 0, g: 1 };
match f {
const { Foo::repeated(22) } => println!("hi"),
_ => println!("1"),
}
}
Эта работа отслеживается в выпуске # 57240. RFC 2920 «const expressions and patterns» (и его проблема с отслеживанием # 76001) также актуальны.
Для меня не сразу очевидно, как это будет работать с вашим точным примером или регулярным выражением без существенных усилий.
Комментарии:
1. я не знал, что это существует, спасибо! я немного приму ваш ответ, предполагая, что до этого не появятся другие ответы, меняющие жизнь ^-^