首頁  >  文章  >  後端開發  >  PHP8.1新特性大講解之Enums枚舉

PHP8.1新特性大講解之Enums枚舉

藏色散人
藏色散人原創
2021-11-10 15:09:314906瀏覽

本文系翻譯,原文網址: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。

#性狀

枚舉可以像類別一樣使用特徵,但有更多限制。不允許覆寫內建的枚舉方法,而且它們不能包含類別屬性 - 枚舉中禁止使用這些屬性。

#反射和屬性

如預期的那樣,加入了一些反射類別來處理枚舉:ReflectionEnum、ReflectionEnumUnitCase和ReflectionEnumBackedCase。還有一個新enum_exists功能,正如它的名字所暗示的那樣。

就像普通的類別和屬性一樣,枚舉及其案例可以使用attributes進行註解。請注意,TARGET_CLASS過濾器還將包括枚舉。

最後一件事:枚舉也有一個唯讀屬性,RFC 提到這是實作細節,應該只用於偵錯目的。不過還是值得一提的。 $enum->name

#

以上是PHP8.1新特性大講解之Enums枚舉的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn