gpt4 book ai didi

rust - 为什么 Rust 不在匹配模式中执行隐式 deref 强制?

转载 作者:行者123 更新时间:2023-12-03 11:23:44 25 4
gpt4 key购买 nike

在阅读了关于 Smart Pointers and Interior mutability 的 Rust 书中的部分之后,作为个人练习,我尝试编写一个函数,该函数将遍历智能指针的链表并返回列表中的“最后一个”元素:

#[derive(Debug, PartialEq)]
enum List {
Cons(Rc<RefCell<i32>>, Rc<List>),
Nil,
}

use crate::List::{Cons, Nil};

fn get_last(list: &List) -> &List {
match list {
Nil | Cons(_, Nil) => list,
Cons(_, next_list) => get_last(next_list),
}
}
此代码导致以下错误:
   |         Nil | Cons(_, Nil) => list,
| ^^^ expected struct `std::rc::Rc`, found enum `List
我能够通过使用“匹配守卫”并明确取消对 Cons(_, x) 的引用来使其工作。图案:
fn get_last(list: &List) -> &List {
match list {
Nil => list,
Cons(_, next_list) if **next_list == Nil => list,
Cons(_, next_list) => get_last(next_list),
}
}
鉴于我对隐式取消引用和 Deref 的了解 Rc 的特征实现,我本来希望我第一次尝试工作。为什么我必须在这个例子中明确取消引用?

最佳答案

首先,我们需要了解什么是取消引用强制。如 T取消引用 Ux是类型 T 的值, 然后:

  • *x*Deref::deref(&x)
  • &T可以强制到&U
  • x.method()将检查类型 U在方法解析期间。

  • 方法解析的工作原理是,当您在类型上调用方法时,它首先通过向类型添加任何内容来检查方法,然后添加 & ,然后添加 &mut ,然后取消引用。因此,在确定调用哪个方法时 x.method() ,它会首先检查一个接受 T 的方法,然后 &T ,然后 &mut T ,然后 U ,然后 &U ,然后 &mut U ( read more here )。此 适用于运营商。因此, ==不会强制不同的类型,这就是您必须明确取消引用的原因。
    但是如果我们确实使用了一个方法,比如 .eqPartialEq特征?事情变得有趣。以下代码失败:
    fn get_last(list: &List) -> &List {
    match list {
    Nil => list,
    Cons(_, next_list) if next_list.eq(Nil) => list,
    Cons(_, next_list) => get_last(next_list),
    }
    }
    但以下成功:
    fn get_last(list: &List) -> &List {
    match list {
    Nil => list,
    // notice how it's Nil.eq and not next_list.eq
    Cons(_, next_list) if Nil.eq(next_list) => list,
    Cons(_, next_list) => get_last(next_list),
    }
    }
    为什么是这样?我们来看第一个例子: next_list类型为 &Rc<List> ,所以它开始搜索 .eq方法。它立即找到在 PartialEq 中定义的一个 Rc 的实现带签名 fn eq(&self, other: &Rc<List>) .然而, other类型为 List在这种情况下,不能强制为 &Rc<List> .
    那为什么第二个工作呢? Nil类型为 List ,所以它开始搜索 .eq方法。找不到 List 的任何内容,所以它会尝试 &List接下来,它找到派生的 PartialEq带签名的实现 fn eq(&self, other: &List) .在这种情况下,other 的类型为 &Rc<List> ,可以强制为 &List因为它的 Deref执行。这意味着所有类型检查都正确并且代码可以正常工作。
    至于为什么你的第一次尝试没有成功,它似乎不是 Rust 的一个特性,还有 a proposal to add it dating back to 2017 .

    关于rust - 为什么 Rust 不在匹配模式中执行隐式 deref 强制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62851229/

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