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 实例化 | 不支持 | 支持 |
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。