Flutter枚举扩展生成插件enum_extendable_generator的使用

Flutter枚举扩展生成插件enum_extendable_generator的使用

Overview

能够为枚举添加字段和方法。

假设我们有以下枚举:

enum MathOperator { plus, minus }

如果可以将枚举值用作某种常规Dart类的实例将会非常方便。例如,

final n1 = 1;
final n2 = 2.0;
MathOperator.values.forEach((operator) {
  print('$n1 ${operator.symbol} $n2 = ${operator.calculate(n1, n2)}');
});

枚举上的扩展可以帮助我们实现这一点。

扩展还可以提供更多功能。我们可以从Dart类的实例获取特定的枚举项,例如以这种方式:

final MathOperator? mathOperator = "+".toMathOperatorFromSymbol();

我们也可以对集合进行操作:

final List<MathOperator?> mathOperators = ['+', '*'].toMathOperatorFromSymbol();

所有这些扩展都可以通过此插件生成。

Usage

Install

首先,在pubspec.yaml文件中添加build_runnerEnumExtendable

# pubspec.yaml
dependencies:
  enum_extendable_annotation:

dev_dependencies:
  build_runner:
  enum_extendable_generator:

然后安装它们:

# Dart
pub get

# Flutter
flutter packages get

包列表:

  • build_runner,用于运行代码生成器;
  • enum_extendable_generator,代码生成器;
  • enum_extendable_annotation,包含用于enum_extendable_generator的注解。

创建一个PODO(Plain Old Data Object)类并添加注解

接下来,我们需要创建一个PODO类来描述枚举的属性。例如,

@ExtendableEnum()
enum MathOperator { plus, minus }

@ExtendableEnumPodo()
class _MathOperatorPodo {
  final String symbol;
  final num Function(num, num) calculate;

  _MathOperatorPodo({
    required this.symbol,
    required this.calculate,
  });

  @ExtendableEnumValues()
  static final Map<MathOperator, _MathOperatorPodo> _values = {
    MathOperator.plus: _MathOperatorPodo(
      symbol: "+",
      calculate: (n1, n2) => n1 + n2,
    ),
    MathOperator.minus: _MathOperatorPodo(
      symbol: "-",
      calculate: (n1, n2) => n1 - n2,
    ),
  };
}

我们想要的枚举项的属性如下:

  final String symbol;
  final num Function(num, num) calculate;

并且在Map<MathOperator, _MathOperatorPodo> _values中为每个枚举项提供一个PODO对象实例。

这里使用了三个注解:

  • 枚举注解 - @ExtendableEnum()
  • PODO类注解 - @ExtendableEnumPodo()
  • 值映射注解 - @ExtendableEnumValues()

运行生成器

如果你的包依赖于Flutter:

flutter pub run build_runner build

如果你的包不依赖于Flutter:

dart pub run build_runner build

EnumExtendable需要我们导入注解并在文件顶部使用part关键字。

因此,要使用EnumExtendable的文件应该以以下方式开始:

import 'package:enum_extendable_annotation/enum_extendable_annotation.dart';

part 'example.enum_extendable.g.dart';

注意:如果PODO对象中存在任何集合字段,则还需要添加一个导入(以便正确比较集合):

import 'package:collection/collection.dart';

特性

扩展

让我们以MathOperator枚举为例来探索可用的扩展。

@ExtendableEnum()
enum MathOperator { plus, minus }

@ExtendableEnumPodo()
class _MathOperatorPodo {
  final String symbol;
  final num Function(num, num) calculate;

@ExtendableEnumValues()
  static final Map<MathOperator, _MathOperatorPodo> _values = {
    ...
  };
1. 枚举上的扩展

此包为PODO类的所有字段生成枚举扩展。

extension MathOperatorExt on MathOperator {
  String get symbol {
    _checkMathOperatorValues();
    return _MathOperatorPodo._values[this]!.symbol;
  }

  num Function(num, num) get calculate {
    _checkMathOperatorValues();
    return _MathOperatorPodo._values[this]!.calculate;
  }
}
2. PODO字段类型类上的扩展

如果我们需要根据PODO类的某个字段值获取特定的枚举项

final MathOperator? mathOperator = "+".toMathOperatorFromSymbol();

则可以使用生成的类扩展:

extension MathOperatorStringExt on String {
  MathOperator? toMathOperatorBySymbol({MathOperator? defaultValue}) {
    _checkMathOperatorValues();
    for (MathOperator element in _MathOperatorPodo._values.keys) {
      if (_MathOperatorPodo._values[element]!.symbol == this) {
        return element;
      }
    }
    return defaultValue;
  }
}
3. 可迭代上的扩展

最后,类似的扩展将为可迭代生成。

extension MathOperatorStringIterableExt on Iterable<String> {
  List<MathOperator?> toMathOperatorBySymbol({MathOperator? defaultValue}) {
    _checkMathOperatorValues();
    return List<MathOperator?>.of(
        map((e) => e.toMathOperatorBySymbol(defaultValue: defaultValue)).toList());
  }

  List<MathOperator> toNotNullMathOperatorBySymbol(
    MathOperator defaultValue,
  ) {
    _checkMathOperatorValues();
    return List<MathOperator>.of(map((e) =>
        e.toMathOperatorBySymbol(defaultValue: defaultValue) ??
        defaultValue).toList());
  }
}

这些扩展允许我们将可迭代映射到枚举项的列表:

final List<MathOperator?> mathOperators = ['+', '-'].toMathOperatorFromSymbol();

更多关于Flutter枚举扩展生成插件enum_extendable_generator的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter枚举扩展生成插件enum_extendable_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


enum_extendable_generator 是一个用于在 Flutter 中生成枚举扩展的代码生成插件。它可以帮助你为枚举类型生成额外的辅助方法或属性,从而增强枚举的功能。

安装步骤

  1. 添加依赖: 在你的 pubspec.yaml 文件中添加 enum_extendable_annotationenum_extendable_generator 依赖。

    dependencies:
      flutter:
        sdk: flutter
      enum_extendable_annotation: ^1.0.0
    
    dev_dependencies:
      build_runner: ^2.1.0
      enum_extendable_generator: ^1.0.0
    
  2. 创建枚举类: 创建一个枚举类,并使用 [@EnumExtendable](/user/EnumExtendable) 注解标记它。

    import 'package:enum_extendable_annotation/enum_extendable_annotation.dart';
    
    [@EnumExtendable](/user/EnumExtendable)()
    enum Status {
      pending,
      approved,
      rejected,
    }
    
  3. 生成代码: 运行 build_runner 来生成代码。

    flutter pub run build_runner build
    

    这将生成一个名为 status_extended.dart 的文件,其中包含扩展方法或属性。

使用生成的代码

生成的代码将包含一个扩展类,你可以使用它来访问生成的属性和方法。

import 'status_extended.dart';

void main() {
  print(Status.pending.displayName); // 输出: Pending
  print(Status.approved.displayName); // 输出: Approved
  print(Status.rejected.displayName); // 输出: Rejected
}

自定义生成的代码

你可以在 [@EnumExtendable](/user/EnumExtendable) 注解中指定一些选项来定制生成的代码。

[@EnumExtendable](/user/EnumExtendable)(
  displayNameFunc: 'toDisplayName',
  valueFunc: 'toValue',
)
enum Status {
  pending,
  approved,
  rejected,
}

这将生成 toDisplayNametoValue 方法,而不是默认的 displayName 属性。

示例

假设你有一个 Status 枚举,并且你想为每个枚举值生成一个 displayName 属性,你可以这样做:

import 'package:enum_extendable_annotation/enum_extendable_annotation.dart';

[@EnumExtendable](/user/EnumExtendable)()
enum Status {
  pending,
  approved,
  rejected,
}

运行 build_runner 后,生成的代码可能如下所示:

extension StatusExtendable on Status {
  String get displayName {
    switch (this) {
      case Status.pending:
        return 'Pending';
      case Status.approved:
        return 'Approved';
      case Status.rejected:
        return 'Rejected';
    }
  }
}
回到顶部