gpt4 book ai didi

rust - 比赛背后的魔力:没有对`&std::option::Option 的实现== std::option::Option <_>

转载 作者:行者123 更新时间:2023-12-03 11:30:49 28 4
gpt4 key购买 nike

我是Python中Rust的新手。这是我学习Rust的第四天。
在第一个问题Type casting for Option type之后,我有一个跟语法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,
}
}
这完美地工作了, ab与没有 None*unwrap_or成功地进行了比较。

这些代码结束于以下问题:
  • 为什么在我的原始代码中需要*与None进行比较?
  • match背后的魔力是什么?这种语法如何使代码跳过(使用*unwrap_or进行比较)?
  • 最佳答案

    Why * is needed to compare with None in my original code?


    本身并不需要,但是 Eq仅针对相同类型实现,因此您需要比较两个 Option<T>或两个 &Option<T>。从中您可能会看到 comparing your nodes to &None would also have worked

    What is the magic behind match? How does this syntax make code skip using * and unwrap_or for comparison?


    Match Ergonomics。基本上, match将尝试自动添加对模式的引用,以尝试解析类型。
    另外我不知道您是否注意到了,只是想更加努力地工作,但是 Option<T: Eq>实现了 Eq,所以 is_same(&a, &b) could just be written a == b
    另外,通常建议不要使用 #[inline],通常最好避免提供提示,除非您专门查看了生成的输出并且编译器拒绝提供您正在寻找的内容。请记住:这里的代码是如此简单,以至于在发行模式下,甚至使用复杂的 is_same版本进行大量取消引用后,llvm都会发现什么,然后加载并格式化一个恒定的 true

    关于rust - 比赛背后的魔力:没有对`&std::option::Option <ListNode>的实现== std::option::Option <_>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62875622/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com