rust-quiz:007-surprise-wildcard-match.rs

题目

#[repr(u8)]
enum Enum {
    First,
    Second,
}

impl Enum {
    fn p(self) {
        match self {
            First => print!("1"),
            Second => print!("2"),
        }
    }
}

fn main() {
    Enum::p(unsafe {
        std::mem::transmute(1u8)
    });
}

关键

  • #[repr(u8)]
    rust的内存布局layer不用在意,这里只要知道这是按照C语言的内存布局即可。
    而在C中,枚举申明其实就是按照数值进行一个个排序声明。
    明显的告诉你,std:: mem::transmute(1u8)解析以后得到的是Enum::Second

  • match
    我们可以使用确切的一些模式去匹配值,也可以忽略一个值_
    但是我们需要这么一个不需要任何匹配却需要获取它的值的时候呢。

    match XXX {
      pat1 => {},
      pat2 => {},
      v => {}
    }

    很简单,只需要一个简单的名称,就能够标识:_匹配,并且获取值。

  • namespace
    path就不断提示,我们又相对路径和绝对路径。
    早就听说过prelude,我们使用use的时候也有全路径或者部分路径的导入。
    这些都来源于一个问题:namespace
    我们需要足够的信息去判断某一个函数或对象,变量或常量的具体位置,具体值。
    当然,这是为了避免冲突。
    但是在某些即使不导入也不冲突的地方,它的作用就是准确的定义这个值本身。

  • enum
    rust中,enum不只是常量枚举这么简单

    • 常量:简单枚举
    • 结构:不同枚举可以定义不同的携带结构
    • 协议:impl相同的动作,不同的内容
    • 方法集:定义在枚举中还是定义在枚举携带的结构中,总能为我们引入方法

审题

很简单,既然传入的是Enum::Second,我们这里主要是执行match
不过遗憾的一个点,也是需要明确的一点是:即使在枚举内部,数据并不共享。
也就是说,即使是在Enum内部,也不能直接使用FirstSecond

java中,同一个class内,调用方法可以有两种方式

  • method
  • this.method

当然,this关键字是可以省略的,但是,rust中的self是不能省略的。
失去了self的限定,就找不到该方法。
除非你是在当前的域中定义的一个方法,才能直接调用。

因此,这里出现的FirstSecond并非枚举,无法进行匹配。
它标识的含义是wildcard全匹配,Second是永远无法到达的痛。

如果想要明确FirstSecond,可以有三个方法

  • 全路径申明:Enum::FirstEnum::Second
  • 自环境引用:Self::FirstSelf::Second
  • 环境导入:use Enum::{First, Second}

答案

First全匹配,结果自然是1

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!