Dart 2.17 - Enum 的新特性

5,924 阅读2分钟

早在21年的5月份我写过一篇文章谈到如何扩展enum,比如他不能自定义value为中文,比如# 不能自由定义枚举从几开始;在本次更新后新增提高生产效率的写法。

最简单的枚举

enum Color { red, green, blue }

增强的枚举

Dart还允许枚举声明使用字段、方法和常量构造函数声明类,这些构造函数限制为固定数量的已知常量实例。

要声明增强的枚举,请遵循类似于普通类的语法,但有一些额外要求:

  • 实例变量必须是final,包括由mixin添加的变量。
  • 所有生成构造函数都必须是常量。
  • 工厂构造函数只能返回一个固定的已知枚举实例。
  • 由于枚举是自动扩展的,因此无法扩展其他类。
  • 索引、哈希代码、相等运算符==不能有重写。
  • 不能在枚举中声明名为values的成员,因为它会与自动生成的静态值getter冲突。
  • 必须在声明的开头声明枚举的所有实例,并且必须至少声明一个实例。

下面是一个示例,它声明了一个具有多个实例、实例变量、getter和实现接口的增强枚举:

enum Vehicle implements Comparable<Vehicle> {
  car(tires: 4, passengers: 5, carbonPerKilometer: 400),
  bus(tires: 6, passengers: 50, carbonPerKilometer: 800),
  bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);

  const Vehicle({
    required this.tires,
    required this.passengers,
    required this.carbonPerKilometer,
  });

  final int tires;
  final int passengers;
  final int carbonPerKilometer;

  int get carbonFootprint => (carbonPerKilometer / passengers).round();

  @override
  int compareTo(Vehicle other) => carbonFootprint - other.carbonFootprint;
}

实现

旧的实现方法

import 'package:flutter/material.dart';
enum Status {
  /// 待发送
  ToBeSent,
  /// 已发送
  HasBeenSent,
  /// 已接收
  Received,
  /// 已回复
  Replied,
  /// 已取消
  Canceled,
}

extension StatusExtension on Status {
  static const List<int> values = [0, 1, 2, 3, -1];
  static const List<String> labels = [
    "待发送",
    "已发送",
    "已接收",
    "已回复",
    "已取消"
  ];
  static const List<Color> colors = [
    Color(0xffb4b4b4),
    Color(0xfff79d8c),
    Color(0xff00b9f1),
    Color(0xff2699f6),
    Color(0xff75d239),
  ];
  /// 真正后台想要的值
  int get value => values[this.index];
  /// 展示文字
  String get label => labels[this.index];
  /// 展示颜色
  Color get color => colors[this.index];
  /// 解析从后台传来的值
  static Status parse(int i) {
    if (i == -1) return Status.Canceled;
    return Status.values[i];
  }
}

新方法

enum Status{
    ToBeSent(value: 0, label: "待发送", color: Color(0xffb4b4b4)),
    HasBeenSent(value: 1, label: "已发送", color: Color(0xfff79d8c)),
    Received(value: 2, label: "已接收", color: Color(0xff00b9f1)),
    Replied(value: 3, label: "已回复", color: Color(0xff2699f6)),
    Canceled(value: -1, label: "已取消", color: Color(0xff75d239));
    
    final int value;
    final String label;
    final Color color;

  const Status({
    required this.value,
    required this.label,
    required this.color,
  });
  
  
  /// 解析从后台传来的值
  static Status parse(int i) {
    if (i == -1) return Status.Canceled;
    return Status.values[i];
  }    
}

新的写法更加一体化

参考文献

Dart 2.17: Productivity and integration