我是Python的生手。这是我学习锈的第四天。
在我的第一个问题可选类型的铸造之后,我有一个关于语法match和所有权概念的后续问题。
首先,我声明了一个带有ListNode实现的new结构。
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ListNode {
pub val: i32,
}
impl ListNode {
#[inline]
fn new(val: i32) -> Self {
ListNode {
val
}
}
}我的目标是通过比较节点的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成功地与没有*和unwrap_or的None进行了比较。
这些代码的结尾是以下问题:
*与原始代码中的任何一个进行比较?match背后的魔力是什么?这种语法如何使代码跳过使用*和unwrap_or进行比较?发布于 2020-07-13 12:56:19
为什么需要将
*与我的原始代码中的None进行比较?
它本身并不需要,但是Eq只是为相同的类型实现的,所以您需要比较两个Option<T>或两个&Option<T>。从这个你可以看到也会起作用。
火柴背后的魔力是什么?这种语法如何使代码跳过使用*和unwrap_or进行比较?
匹配人机工程学。基本上,match将尝试自动添加对模式的引用,以便尝试和解析这些类型。
另外,我不知道您是否注意到并只想更努力地工作,但是Option<T: Eq>实现了Eq,所以is_same(&a, &b) a == b。
还有一件事,#[inline]通常被反对,通常最好避免提供提示,除非您专门查看了生成的输出,而编译器拒绝提供您想要的结果。请记住:这里的代码是如此简单,以至于在发布模式下,甚至在使用复杂版本的is_same时,llvm会发现什么是什么,并且只是加载和格式化一个常量的true。
https://stackoverflow.com/questions/62875622
复制相似问题