PHP8.1公布了, 一个 enum 就有好多货色要留神.
enum
基本上就是一个限定类, 先看看它的语法结构是什么样的.
<code class="c">enum_declaration_statement: T_ENUM { $<num>$ = CG(zend_lineno); } T_STRING enum_backing_type implements_list backup_doc_comment '{' class_statement_list '}' { $$ = zend_ast_create_decl(ZEND_AST_CLASS, ZEND_ACC_ENUM|ZEND_ACC_FINAL, $<num>2, $6, zend_ast_get_str($3), NULL, $5, $8, NULL, $4); } ;
enum
关键字打头, 前面可选跟: (string|int)
, 因为是类所以能够实现接口 implement SomeInterface, MoreInterface
, 又因为加了 ZEND_ACC_FINAL
, 相当于 final class className
, 所以是不能继承别的枚举类型.
定义
<code class="php"><?php //不初始化值,间接这样定义是能够的 enum Week { case Monday; } //这样是谬误的,外面的枚举元素初始化值,必须指定整个枚举类型的变量类型,string 或者 int enum Week { case Monday = 'monday'; } //正确的形式 enum Week: string { case Monday = 'monday'; }
enum的一些特定操作
<code class="php"><?php enum Week: string { case Monday = 'monday'; case Tuesday = 'tuesday'; } //获取枚举类型元素的值 echo Week::Monday->value; //获取枚举类型元素的key echo Week::Monday->name;
Week::Monday
就是这个枚举类型的一个实例,相当于一般类的 object
.
留神枚举类型
不能被实例化
,也没有结构和析构函数。如果用new
去实例化Week
,会失去一个fatal error
.
通过值获取实例
<code class="php">enum Week: string { case Monday = 'monday'; case Tuesday = 'tuesday'; } var_dump(Week::from('monday')); var_dump(Week::tryFrom('money'));
Week::from
返回的是 Worker::Monday
,是 Week
的一个实例。tryFrom
跟 from
的区别在于如果传递一个不存在的值,form
会报错,而 tryFrom
返回的是 null
.
tryFrom
配合新语法,代码会更加精简.
<code class="php">//不应用 tryFrom try { $value = Week::from('no_exists_value')->value; } catch (Throwable $e) { $value = null; } //应用 tryFrom 加新语法 $value = Week::tryFrom('no_exists_value')?->value;
tips:
from
和tryFrom
办法是不能被重写的.
enum 定义方法
<code class="php">enum Week: string { case Monday = 'monday'; case Tuesday = 'tuesday'; public function test() { echo 'test'. PHP_EOL; } } Week::Monday->test();
调用和一般类一样,实例->办法名,所以只有牢记 Week::Monday
返回的是实例,其它操作跟类高度类似。
enum 实现接口
<code class="php"><?php interface TestInterface { public function test(); } interface MultiInterface { public function func(); } enum Week: string implements TestInterface, MultiInterface { case Monday = 'monday'; case Tuesday = 'tuesday'; public function test() { echo 'test'. PHP_EOL; } public function func() { echo 'multi interface func'. PHP_EOL; } }
enum应用trait
<code class="php">trait Testable { public function test() { echo 'test'.PHP_EOL; } } enum Week: string { use Testable; case Monday = 'monday'; case Tuesday = 'tuesday'; }
enum 获取实例列表
<code class="php"><?php enum Week: string { case Monday = 'monday'; case Tuesday = 'tuesday'; } var_dump(Week::cases());
tips:
cases
办法也不能被重写.
判断一个 enum 是否存在
<code class="php"><?php enum Week: string { case Monday = 'monday'; case Tuesday = 'tuesday'; } var_dump(enum_exists('Week'));
其它
- 因为
enum
实质上还是一个类,所以有些一般类的函数,enum
也能用,比方instanceof
.
<code class="php"><?php var_dump(Week::Monday instanceof Week);
- 应用
::class
返回齐全限定名,同样实用于enum
类型. - 命名空间也根本和类统一.
- 定义字符串,也能够用
heredoc
语法.
<code class="php"><?php enum Week: string { const Monday = <<<MONDAY This is monday. MONDAY; }
ENUM和一般类的比照
ENUM | 一般类 | |
---|---|---|
构造函数 | 不反对 | 反对 |
析构函数 | 不反对 | 反对 |
序列化函数 | 不反对 | 反对 |
反序列化函数 | 不反对 | 反对 |
克隆函数 | 不反对 | 反对 |
类属性 | 不反对 | 反对 |
动静属性 | 不反对 | 反对 |
用 new 实例化 | 不反对 | 反对 |