站长资讯网
最全最丰富的资讯网站

PHP8.1新特性大讲解之Enums枚举

本文系翻译,原文地址:https://stitcher.io/blog/php-enums

PHP 8.1:枚举

它们终于来了——PHP 8.1中将添加对枚举的内置支持!有些人可能认为他们早就应该这样做了,但你没有听到我的抱怨;我很高兴他们做到了!这篇文章致力于深入研究新添加的功能。

像往常一样,在我的 PHP 功能帖子中,我们首先对枚举的外观进行高级概述:

enum Status {     case DRAFT;     case PUBLISHED;     case ARCHIVED; }

枚举的好处是它们代表了一组常量值,但最重要的是这些值可以被键入,如下所示:

class BlogPost {     public function __construct(         public Status $status,      ) {} }

在这个例子中,创建一个枚举并将其传递给 aBlogPost看起来像这样:

$post = new BlogPost(Status::DRAFT);

这就是基础知识,正如您所看到的,它们一点也不复杂。虽然有很多旁注需要做,让我们深入看看枚举!

#枚举方法

枚举可以定义方法,就像类一样。这是一个非常强大的功能,尤其是与match运算符结合使用时:

enum Status {     case DRAFT;     case PUBLISHED;     case ARCHIVED;          public function color(): string     {         return match($this)          {             Status::DRAFT => 'grey',                Status::PUBLISHED => 'green',                Status::ARCHIVED => 'red',            };     } }

方法可以像这样使用:

$status = Status::ARCHIVED; $status->color(); // 'red'

静态方法也是允许的:

enum Status {     // …          public static function make(): Status     {         // …     } }

您还可以self在枚举中使用:

enum Status {     // …          public function color(): string     {         return match($this)          {             self::DRAFT => 'grey',                self::PUBLISHED => 'green',                self::ARCHIVED => 'red',            };     } }

#枚举接口

枚举可以实现接口,就像普通类一样:

interface HasColor {     public function color(): string; } enum Status implements HasColor {     case DRAFT;     case PUBLISHED;     case ARCHIVED;          public function color(): string { /* … */ } }

#枚举值——又名“支持枚举”

枚举值在内部由对象表示,但您可以根据需要为它们赋值;这对于例如很有用。将它们序列化到数据库中。

enum Status: string {     case DRAFT = 'draft';     case PUBLISHED = 'published';     case ARCHIVED = 'archived'; }

注意枚举定义中的类型声明。它表示所有枚举值都属于给定类型。您也可以将其设为int. 请注意, onlyint和string允许作为枚举值。

enum Status: int {     case DRAFT = 1;     case PUBLISHED = 2;     case ARCHIVED = 3; }

类型枚举的技术术语称为“支持枚举”,因为它们由更简单的值“支持”。如果您决定分配枚举值,则所有案例都应该有一个值。你不能混合和匹配它们。没有“支持”的枚举被称为“纯枚举”。

#带接口的支持枚举

如果您将支持的枚举和接口结合使用,则枚举类型必须直接位于枚举名称之后,implements关键字之前。

enum Status: string implements HasColor {     case DRAFT = 'draft';     case PUBLISHED = 'published';     case ARCHIVED = 'archived';          // … }

#序列化支持的枚举

如果您要为枚举案例分配值,您可能需要一种方法来序列化和反序列化它们。序列化它们意味着您需要一种访问枚举值的方法。这是通过只读公共属性完成的:

$value = Status::PUBLISHED->value; // 2

可以使用以下方法从值中恢复枚举:Enum::from

$status = Status::from(2); // Status::PUBLISHED

如果传递了未知值tryFrom,还有一个返回null。如果你会使用from会有一个例外。

$status = Status::from('unknown'); // ValueError $status = Status::tryFrom('unknown'); // null

请注意,您还可以在枚举上使用内置函数serialize和unserialize函数。此外,您可以json_encode与支持的枚举结合使用,其结果将是枚举值。可以通过实现来覆盖此行为JsonSerializable。

#列出枚举值

您可以使用静态方法获取枚举中所有可用案例的列表:Enum::cases()

Status::cases(); /* [     Status::DRAFT,      Status::PUBLISHED,      Status::ARCHIVED ] */

请注意,此数组包含实际的枚举对象:

array_map(     fn(Status $status) => $status->color(),      Status::cases() );

#枚举是对象

我已经提到枚举值表示为对象,实际上它们是单例对象。这意味着您可以像这样与它们进行比较:

$statusA = Status::PENDING; $statusB = Status::PENDING; $statusC = Status::ARCHIVED; $statusA === $statusB; // true $statusA === $statusC; // false $statusC instanceof Status; // true

#枚举作为数组键

由于枚举值实际上是对象,因此目前无法将它们用作数组键。以下将导致错误:

$list = [     Status::DRAFT => 'draft',     // … ];

有一个 RFC来改变这种行为,但它还没有被投票。

这意味着您只能使用枚举作为SplObjectStorage和 中的键WeakMaps。

#性状

枚举可以像类一样使用特征,但有

赞(0)
分享到: 更多 (0)
网站地图   沪ICP备18035694号-2    沪公网安备31011702889846号