对此PHP中enum的奇异

PHP中从未struct、enum那些事物,尽管万能的array用起来很爽,但写出来的代码typo难题重重、可维护性也差,必要越多的测试来协理,而只要拉长测试的工作量是还是不是还谈得上『爽』就是个问号了。

看了一篇切磋Java
enum机制的稿子,小说里提到java的实际的enum其实就是一个类,重点是它的每贰个枚举值也是一个enum对象。

比较着用PHP初叶达成了一晃。PHP的__callStatic
不支持静态属性访问,所以暂且用静态方法的样式拜访枚举值 (string)
Color::RED()。

<?php

interface enum
{

}

/**
 * @method enum RED() Description
 */
final class Color implements enum
{    
    private static $enums = 
        [
            'RED' => [255, 0, 0],
            'BLUE' => [0, 0, 255],
            'BLACK' => [0, 0, 0],
            'YELLOW' => [255, 255, 0],
            'GREEN' => [0, 255, 0]
        ];
    private static $objs = [];

    private $name;

    public static function __callStatic($name, $arguments)
    {
        if (!array_key_exists($name, static::$enums)) {
            throw new Exception('enum not existed', -1);
        }

        return static::valueOf($name);
    }

    private function setName($val): void
    {
        $this->name = $val;
    }

    private static function initEnum(string $name): bool
    {
        if (isset(static::$objs[$name])) {
            return true;
        }

        if (!array_key_exists($name, static::$enums)) {
            throw new Exception('enum not existed', -1);
        }

        $obj = new Color();
        $obj->setName($name);

        static::$objs[$name] = $obj;

        return true;
    }

    public static function values(): array
    {
        if (empty(static::$objs)) {
            foreach (array_keys(static::$enums) as $name) {
                static::initEnum($name);
            }
        }

        return static::$objs;
    }

    public static function valueOf(string $name): enum
    {
        if (!array_key_exists($name, static::$enums)) {
            throw new Exception('enum not existed', -1);
        }

        static::initEnum($name);

        return static::$objs[$name];
    }

    public function ordinal(): int
    {
        //TODO
        return 0;
    }

    /**
     * @throws ClassCastException
     */
    public function compareTo(enum $other): int
    {
        //TODO
        return -1;
    }

    public function equals(enum $other): bool
    {
        //TODO
        return true;
    }

    public function __toString()
    {
        if (!$this->name) {
            return '';
        }

        return '(' . implode(',', static::$enums[$this->name]) . ')';
    }
}  


echo (string) Color::RED();
echo (string) Color::valueOf('BLACK');

代码并没有做仔细的肤浅,假如要特别抽象的话,能够试行定义1个EnumTraits来含有那二个公共措施。

会不会有人问,既然您如此喜欢Java的enum,为啥不直接用Java得了。

相关文章