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を使って)ソートできています。
参考