Имеется код
fn translate_char(c: &char) -> char{
if c.is_numeric(){ return *c; }
match c {
&'Н' => 'V',
&'П' => 'Z',
_ => panic!("Can't translate char {}", c),
}
}
Ссылки на уровне ассемблера - это же указатели, так? В моем понимании match должна сравнить по указателям, но она сравнивает по содержимому. Как так? Магия какая-то.
Точно, это
магия:sparkles:. Это заклинание называется pattern matching.
match
ничего не сравнивает, он сопоставляет шаблону. Слева от стрелок находится не значение c которым сравнивается переменная, а шаблон которому сопоставляется значение переменной c
.
Ссылки можно разбирать так же как и структуры (Деструктуризация).
Этот код полностью эквивалентен вашему примеру:
match *c {
'Н' => 'V',
'П' => 'Z',
_ => panic!("Can't translate char {}", c),
}
К тому же в Rust операция сравнения (trait Eq
) переопределена для ссылок и других указателей Box
, Rc
, Arc
. Этот код выведет true
:
let a = 'A';
let b = 'A';
println!("{}", &a == &b);
Чтобы узнать на одно место указывают ссылки или нет, нужно преобразовать их в сырые указатели (raw ptr
):
let a = 'A';
let b = 'A';
println!("{}", &a as *const char == &b as *const char);
P.S. Ссылки не тоже самое, что ассемблерные указатели. Например, размеры ссылок на Sized
и !Sized
типы отличаются.
3 лайка
тут про F#, но суть того как выполняется сопоставление с образцом примерно та же