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
内部,也不能直接使用First
和Second
。
在java
中,同一个class
内,调用方法可以有两种方式
method
this.method
当然,this
关键字是可以省略的,但是,rust
中的self
是不能省略的。
失去了self
的限定,就找不到该方法。
除非你是在当前的域中定义的一个方法,才能直接调用。
因此,这里出现的First
和Second
并非枚举,无法进行匹配。
它标识的含义是wildcard
全匹配,Second
是永远无法到达的痛。
如果想要明确First
和Second
,可以有三个方法
- 全路径申明:
Enum::First
和Enum::Second
- 自环境引用:
Self::First
和Self::Second
- 环境导入:
use Enum::{First, Second}
答案
First
全匹配,结果自然是1
。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: