PHP8.1之enum解析
source link: https://segmentfault.com/a/1190000041091095
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
PHP8.1之enum解析
PHP8.1发布了, 一个 enum 就有好多东西要注意.
enum
基本上就是一个限定类, 先看看它的语法结构是什么样的.
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
, 所以是不能继承别的枚举类型.
<?php //不初始化值,直接这样定义是可以的 enum Week { case Monday; } //这样是错误的,里面的枚举元素初始化值,必须指定整个枚举类型的变量类型,string 或者 int enum Week { case Monday = 'monday'; } //正确的方式 enum Week: string { case Monday = 'monday'; }
enum的一些特定操作
<?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
.
通过值获取实例
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
配合新语法,代码会更加精简.
//不使用 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 定义方法
enum Week: string { case Monday = 'monday'; case Tuesday = 'tuesday'; public function test() { echo 'test'. PHP_EOL; } } Week::Monday->test();
调用和普通类一样,实例->方法名,所以只要牢记 Week::Monday
返回的是实例,其它操作跟类高度相似。
enum 实现接口
<?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
trait Testable { public function test() { echo 'test'.PHP_EOL; } } enum Week: string { use Testable; case Monday = 'monday'; case Tuesday = 'tuesday'; }
enum 获取实例列表
<?php enum Week: string { case Monday = 'monday'; case Tuesday = 'tuesday'; } var_dump(Week::cases());
tips:
cases
方法也不能被重写.
判断一个 enum 是否存在
<?php enum Week: string { case Monday = 'monday'; case Tuesday = 'tuesday'; } var_dump(enum_exists('Week'));
- 因为
enum
本质上还是一个类,所以有些普通类的函数,enum
也能用,比如instanceof
.
<?php var_dump(Week::Monday instanceof Week);
- 使用
::class
返回完全限定名,同样适用于enum
类型. - 命名空间也基本和类一致.
- 定义字符串,也可以用
heredoc
语法.
<?php enum Week: string { const Monday = <<<MONDAY This is monday. MONDAY; }
ENUM和普通类的对比
ENUM普通类构造函数不支持支持析构函数不支持支持序列化函数不支持支持反序列化函数不支持支持克隆函数不支持支持类属性不支持支持动态属性不支持支持用 new 实例化不支持支持Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK