PHP8.1之enum解析

PHP8.1发布了, 一个 enum 就有好多东西要注意.

enum 基本上就是一个限定类, 先看看它的语法结构是什么样的.

enum_declaration_statement:
        T_ENUM { $$ = 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, $2, $6, zend_ast_get_str($3), NULL, $5, $8, NULL, $4); }
;

enum 关键字打头, 后面可选跟: (string|int), 因为是类所以可以实现接口 implement SomeInterface, MoreInterface, 又因为加了 ZEND_ACC_FINAL, 相当于 final class className, 所以是不能继承别的枚举类型.

定义

enum的一些特定操作

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 的一个实例。tryFromfrom 的区别在于如果传递一个不存在的值,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: fromtryFrom 方法是不能被重写的.

enum 定义方法

enum Week: string {
    case Monday = 'monday';
    case Tuesday = 'tuesday';
    
    public function test() {
        echo 'test'. PHP_EOL;
    }
}

Week::Monday->test();

调用和普通类一样,实例->方法名,所以只要牢记 Week::Monday 返回的是实例,其它操作跟类高度相似。

enum 实现接口

enum使用trait

trait Testable {
    public function test() {
        echo 'test'.PHP_EOL;
    }
}

enum Week: string {
    use Testable;

    case Monday = 'monday';
    case Tuesday = 'tuesday';
}

enum 获取实例列表

tips: cases 方法也不能被重写.

判断一个 enum 是否存在

其它

  1. 因为 enum 本质上还是一个类,所以有些普通类的函数,enum 也能用,比如 instanceof.
  1. 使用 ::class 返回完全限定名,同样适用于 enum 类型.
  2. 命名空间也基本和类一致.
  3. 定义字符串,也可以用 heredoc 语法.

ENUM和普通类的对比

ENUM 普通类
构造函数 不支持 支持
析构函数 不支持 支持
序列化函数 不支持 支持
反序列化函数 不支持 支持
克隆函数 不支持 支持
类属性 不支持 支持
动态属性 不支持 支持
用 new 实例化 不支持 支持

你可能感兴趣的:(phpphp8enum)