Я новичок в ie в Rust из Python. Это мой 4-й день изучения Rust.
После моего первого вопроса Приведение типов для типа Option , у меня есть следующий вопрос, связанный с синтаксисом match
и концепцией владения.
Во-первых, я объявляю структуру ListNode
с реализацией new
.
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ListNode {
pub val: i32,
}
impl ListNode {
#[inline]
fn new(val: i32) -> Self {
ListNode {
val
}
}
}
Моя цель - сравнить, совпадают ли два узла, сравнивая значение узла. Вот моя уродливая реализация.
fn is_same(a: &Option<ListNode>, b: &Option<ListNode>) -> bool {
if a == None && b == None { return true; }
else if a == None && b != None { return false; }
else if a != None && b == None { return false; }
let ca: ListNode = a.clone().unwrap_or(ListNode::new(0));
let cb: ListNode = b.clone().unwrap_or(ListNode::new(0));
if ca.val == cb.val { return true; }
else { return false; }
}
fn main() {
let a: Option<ListNode> = Some(ListNode::new(0));
let b: Option<ListNode> = Some(ListNode::new(0));
println!("{:?}", is_same(&a, &b));
}
Затем у меня было много ошибок ...
no implementation for `&std::option::Option<ListNode> == std::option::Option<_>
Согласно моим знаниям концепции владения, использование *
для заимствованного параметра должно быть необязательным . Но, чтобы сравнение работало, мне нужно добавить *
. Ниже доработанная функция работает. (Еще одно обнаруженное заключается в том, что использование a.clone()
нормально, но *a.clone()
неверно с ошибкой type `ListNode` cannot be dereferenced
.)
fn is_same(a: &Option<ListNode>, b: &Option<ListNode>) -> bool {
if *a == None && *b == None { return true; }
else if *a == None && *b != None { return false; }
else if *a != None && *b == None { return false; }
let ca: ListNode = a.clone().unwrap_or(ListNode::new(0));
let cb: ListNode = b.clone().unwrap_or(ListNode::new(0));
if ca.val == cb.val { return true; }
else { return false; }
}
Поскольку приведенный выше код решения слишком уродлив, вот другая реализация с использованием match
без избыточных unwrap_or
и *
.
fn is_same(a: &Option<ListNode>, b: &Option<ListNode>) -> bool {
match (a, b) {
(None, None) => true,
(None, _) => false,
(_, None) => false,
(Some(a), Some(b)) => a.val == b.val,
}
}
Это отлично работает, a
и b
успешно сравниваются с None
без *
и unwrap_or
.
Этот код заканчивается следующими вопросами:
- Почему
*
необходимо сравнивать с None в моем исходном коде? - Что такое маг c за
match
? Как этот синтаксис заставляет код пропускать, используя *
и unwrap_or
для сравнения?