zoukankan      html  css  js  c++  java
  • 对于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');
    
    

    代码并没有做细致的抽象,如果要进一步抽象的话,可以试试定义一个EnumTraits来包含那些公共方法。

    会不会有人问,既然你这么喜欢Java的enum,为什么不直接用Java得了。

  • 相关阅读:
    条形码识别
    使用边缘检测,将图像旋转到水平位置
    pyzbar 安装
    关于跑别人代码中遇到的问题
    %matplotlib inline
    git 相关流程和报错解决
    原码、反码和补码
    opencv 图像resize
    前端跨域解决方案汇总
    vuecli3 引入构建版本的2种方式
  • 原文地址:https://www.cnblogs.com/x3d/p/6707265.html
Copyright © 2011-2022 走看看