2022/6/20/Dart/Enhanced enumsを使ってみよう

 

Dart2.17で導入されたEnhanced enumsの使い方をサンプルコードで確認しましょう。

まずこれまでのenumでは、それぞれの列挙型の値がint型・String型などのデータを保持しているような実装をしたい場合(下記サンプルではint型)、下記のように書く必要がありました。

enum OldVehicle{
  car,
  bus,
  bicycle,
}

extension OldVehicleX on OldVehicle{

  int get tires{
    switch(this){
      case OldVehicle.car:
        return 4;
      case OldVehicle.bus:
        return 6;
      case OldVehicle.bicycle:
        return 2;
    }
  }

  int get passengers{
    switch(this){
      case OldVehicle.car:
        return 5;
      case OldVehicle.bus:
        return 50;
      case OldVehicle.bicycle:
        return 1;
    }
  }

  int get carbonPerKilometer{
    switch(this){
      case OldVehicle.car:
        return 400;
      case OldVehicle.bus:
        return 800;
      case OldVehicle.bicycle:
        return 0;
    }
  }

  int get carbonFootprint{
    return (carbonPerKilometer/passengers).round();
  }
}

 

  test('OldVehicle test',(){
    expect(OldVehicle.car.carbonFootprint,80);
    expect(OldVehicle.bus.carbonFootprint,16);
    expect(OldVehicle.bicycle.carbonFootprint,0);

    expect(OldVehicle.car.carbonFootprint > OldVehicle.bus.carbonFootprint, isTrue);
    expect(OldVehicle.bus.carbonFootprint > OldVehicle.bicycle.carbonFootprint, isTrue);
    expect(OldVehicle.bicycle.carbonFootprint < OldVehicle.car.carbonFootprint, isTrue);

    expect(OldVehicle.car.tires , 4);
    expect(OldVehicle.bus.tires , 6);
    expect(OldVehicle.bicycle.tires , 2);

    expect(OldVehicle.car.passengers , 5);
    expect(OldVehicle.bus.passengers , 50);
    expect(OldVehicle.bicycle.passengers , 1);
  });
//tests passed

 


Enhanced enumsでは下記のように、クラスを宣言するような形で定義できるようになりました。

enum Vehicle implements Comparable<Vehicle> {
  //↓全てのインスタンスをenum定義の最初に宣言する。
  car(tires: 4, passengers: 5, carbonPerKilometer: 400),//80
  bus(tires: 6, passengers: 50, carbonPerKilometer: 800),//16
  bicycle(tires: 2, passengers: 1, carbonPerKilometer: 0);//0

  //↓コンストラクタはconstコンストラクタにする。
  const Vehicle({
    required this.tires,
    required this.passengers,
    required this.carbonPerKilometer,
  });

  //↓インスタンス変数(フィールド)は全てfinalにする。
  final int tires;
  final int passengers;
  final int carbonPerKilometer;

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

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


void main(){

  List<Vehicle> vehicles = [
    Vehicle.car,
    Vehicle.bicycle,
    Vehicle.bus,
  ];

  vehicles.sort();

  for(final v in vehicles){
    print('${v.name} : ${v.carbonFootprint}');
  }
}
//↓carbonFootprintを基準としてソートすることができました。
//flutter: bicycle : 0
//flutter: bus : 16
//flutter: car : 80

 

  test('Vehicle test',(){
    expect(Vehicle.car.carbonFootprint,80);
    expect(Vehicle.bus.carbonFootprint,16);
    expect(Vehicle.bicycle.carbonFootprint,0);

    //↓こう書かなくても良い。
    //expect(Vehicle.car.carbonFootprint > Vehicle.bus.carbonFootprint, isTrue);
    //expect(Vehicle.bus.carbonFootprint > Vehicle.bicycle.carbonFootprint, isTrue);
    //expect(Vehicle.bicycle.carbonFootprint < Vehicle.car.carbonFootprint, isTrue);

    expect(Vehicle.car.compareTo(Vehicle.bus) > 0, isTrue);
    expect(Vehicle.bus.compareTo(Vehicle.bicycle) > 0, isTrue);
    expect(Vehicle.bicycle.compareTo(Vehicle.car) < 0, isTrue);


    expect(Vehicle.car.tires , 4);
    expect(Vehicle.bus.tires , 6);
    expect(Vehicle.bicycle.tires , 2);

    expect(Vehicle.car.passengers , 5);
    expect(Vehicle.bus.passengers , 50);
    expect(Vehicle.bicycle.passengers , 1);
  });
//Tests passed

一応全てのenumはEnumクラスのサブクラスである、ということなので列挙型Vehicleも一応クラス、ということになると思います。

Comparableインターフェースを実装したので、sortメソッドで適切に(carbonFootprintを使って)ソートできています。

詳しくはこちらで確認してください。

参考

language-tour

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です