2.7PHP类(Class)类型之枚举(Enumeration)

Enum 本质是一个类(Class),它的各种条目(case)是这个类的单例对象,又近似于可以理解为类常量。

<?php
interface Colorful
{
    public function color(): string;
}

final class Suit implements UnitEnum, Colorful
{
    public const Hearts = new self('Hearts');
    public const Diamonds = new self('Diamonds');
    public const Clubs = new self('Clubs');
    public const Spades = new self('Spades');

    private function __construct(public readonly string $name) {}

    public function color(): string
    {
        return match($this) {
            Suit::Hearts, Suit::Diamonds => 'Red',
            Suit::Clubs, Suit::Spades => 'Black',
        };
    }

    public function shape(): string
    {
        return "Rectangle";
    }

    public static function cases(): array
    {
        // 不合法的方法,Enum 中不允许手动定义 cases() 方法
        // 参考 “枚举值清单” 章节
    }
}
?>

1.纯粹(Pure)枚举

如果条目(case)没有关联数据,就称为“纯粹条目”(Pure Case)。

仅包含纯粹条目的枚举就称为“纯粹枚举“(Pure Enum)。

//PHP < 8.1
class Status
{
    const DRAFT = 'draft';
    const PUBLISHED = 'published';
    const ARCHIVED = 'archived';
}
function acceptStatus(string $status) {...}
//PHP 8.1
enum Status
{
    case Draft;
    case Published;
    case Archived;
}
function acceptStatus(Status $status) {...}

2.回退(Backed)枚举

由于有标量的条目回退(Backed)到一个更简单值,就称为“回退条目”(Backed Case)。

仅包含所有回退条目的枚举就称为“回退枚举”(Backed Enum)。

回退枚举仅能回退到 int 或 string 里的一种类型(不能联合 int|string)。

<?php
enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}
?>

3.访问case

<?php
enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}
?>

访问枚举的case类似于类访问类常量的方式。

Suit::Hearts、Suit::Diamonds、 Suit::Clubs、Suit::Spades

4.访问case的name和value

所有的 case 有个只读的属性 name。 它大小写敏感,是 case 自身的名称。 在调试场景中比较有用。

<?php
print Suit::Spades->name;
// 输出 "Spades"
?>

回退条目有个额外的只读属性 value, 它是定义时指定的值。

<?php
print Suit::Clubs->value;
// 输出 "C"
?>

5.枚举常量

枚举常量可以引用枚举条目:

<?php
enum Size
{
    case Small;
    case Medium;
    case Large;

    public const Huge = self::Large;
}
?>

6.枚举静态方法

枚举也能有静态方法。 在枚举中静态方法主要用于取代构造器,如:

<?php
enum Size
{
    case Small;
    case Medium;
    case Large;

    public static function fromLength(int $cm): static
    {
        return match(true) {
            $cm < 50 => static::Small,
            $cm < 100 => static::Medium,
            default => static::Large,
        };
    }
}
?>

7.枚举实例方法和实现接口

枚举(包括纯粹枚举、回退枚举)还能包含方法, 也能实现 interface。 如果 Enum 实现了 interface,则其中的条目也能接受 interface 的类型检测。

<?php
interface Colorful
{
    public function color(): string;
}

enum Suit implements Colorful
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;

    // 满足 interface 契约。
    public function color(): string
    {
        return match($this) {
            Suit::Hearts, Suit::Diamonds => 'Red',
            Suit::Clubs, Suit::Spades => 'Black',
        };
    }

    // 不是 interface 的一部分;也没问题
    public function shape(): string
    {
        return "Rectangle";
    }
}

function paint(Colorful $c) { ... }

paint(Suit::Clubs);  // 正常

print Suit::Diamonds->shape(); // 输出 "Rectangle"
?>

8.继承

不支持继承。无法 extend 一个 enum。

9.构造函数和析构函数

禁止构造、析构函数。

10.静态变量和实例变量

不支持静态变量和实例变量。

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/php/phplang/10516.html

(0)
上一篇 2021年2月7日 03:40
下一篇 2021年2月8日 20:39

相关推荐

  • 2.6PHP复合(Compound)类型之可调用(callable)

    回调函数可以通过 可调用(callable) 类型声明来表示。 可调用 (callable) 类型的本质是回调函数。 回调函数 回调函数可以是简单函数,还可以是类静态方法,匿名函数,箭头函数。 调用回调函数 PHP是将回调函数以string形式传递的。 call_user_func 第一个参数 $c…

    PHP语言教程 2021年2月6日
    0550
  • 1.1PHP语言的标记(Tag)

    PHP 脚本以 <?php 开头,以 ?> 结尾。 PHP解释器会执行 <?php 和 ?> 标记内的代码,标记外的内容会原封不动地输出。 如果文件内容仅仅包含 PHP 代码,最好在文件末尾删除 PHP 结束标记。这可以避免在 PHP 结束标记之后万一意外…

    PHP语言教程 2021年1月1日
    02330
  • 5.2PHP语言的生成器(Generator)

    生成器提供了一种更容易的方法来实现简单的对象迭代。 相比较定义类实现 Iterator 接口的方式,相同的是调用生成器函数时会返回一个内部的 Generator 类的对象,该 Generator 类实现了 Iterator 接口。不同的是,生成器性能…

    PHP语言教程 2021年5月2日
    01510

发表评论

登录后才能评论