Open2
enumを詳しく調べる

1. enumの基本概念
1.1 enumとは
enumは固定の定数値を表現するための特別なクラスです。
enum Status {
active,
inactive,
pending
}
注意点:
- enumの各値は大文字から始めることも可能ですが、Dartのスタイルガイドでは小文字を推奨しています
- コンマの後にスペースを入れるのが推奨された書き方です
- 最後の要素の後にもカンマを付けることができます(trailing comma)
1.2 enumの特徴
enum Status {
active,
inactive,
pending, // trailing comma
}
void main() {
final status = Status.active;
print(status); // 出力: Status.active
}
重要な特徴:
- 自動的に
Enum
クラスを継承します - シールドされており、継承できません
- インスタンス化できません
- 定数値として扱われます
1.3 基本的なプロパティ
1.3.1 index
各値は自動的に0から始まるインデックスを持ちます。
void main() {
print(Status.active.index); // 出力: 0
print(Status.inactive.index); // 出力: 1
print(Status.pending.index); // 出力: 2
}
注意点:
- インデックスは変更できません
- 値の順序を変更するとインデックスも変更されます
- インデックスに依存したロジックは避けるべきです
1.3.2 name
各値は文字列としての名前を持ちます。
void main() {
print(Status.active.name); // 出力: "active"
print(Status.inactive.name); // 出力: "inactive"
}
注意点:
- nameプロパティは変更できません
- 文字列比較よりもenum値の直接比較を推奨します
2. 拡張されたenum(Enhanced Enum)
2.1 フィールドの追加
enum Device {
smartphone(screenSize: 5.8, hasCamera: true),
tablet(screenSize: 10.1, hasCamera: true),
desktop(screenSize: 27.0, hasCamera: false);
const Device({
required this.screenSize,
required this.hasCamera,
});
final double screenSize;
final bool hasCamera;
}
注意点:
- すべてのフィールドは
final
でなければなりません - コンストラクタは
const
である必要があります - 必須パラメータには
required
キーワードを使用します
2.2 メソッドの追加
enum Device {
smartphone(screenSize: 5.8, hasCamera: true),
tablet(screenSize: 10.1, hasCamera: true),
desktop(screenSize: 27.0, hasCamera: false);
const Device({
required this.screenSize,
required this.hasCamera,
});
final double screenSize;
final bool hasCamera;
// ゲッター
bool get isPortable => this != Device.desktop;
// メソッド
String getDescription() {
return 'Device with ${screenSize}inch screen'
'${hasCamera ? ' and camera' : ''}';
}
}
注意点:
- メソッド内で
this
を使用できます - オーバーライド禁止のメソッドがあります(index, hashCode, ==など)
- メソッドは各enumインスタンスで同じ動作をする必要があります
2.3 インターフェースの実装
enum Priority implements Comparable<Priority> {
low(value: 0),
medium(value: 1),
high(value: 2);
const Priority({required this.value});
final int value;
int compareTo(Priority other) => value.compareTo(other.value);
}
注意点:
- 複数のインターフェースを実装できます
- すべての抽象メソッドを実装する必要があります
- mixinは使用できません
3. 実践的な使用方法
3.1 switch文での使用
enum ConnectionStatus {
connected,
disconnected,
waiting
}
void handleConnection(ConnectionStatus status) {
switch (status) {
case ConnectionStatus.connected:
print('接続されました');
break;
case ConnectionStatus.disconnected:
print('切断されました');
break;
case ConnectionStatus.waiting:
print('接続待ち');
break;
}
}
注意点:
- すべてのケースを網羅する必要があります
-
default
ケースを使用する場合は、将来の拡張性を考慮してください -
break
を忘れないようにしましょう
3.2 値の検証
enum PaymentType {
creditCard,
debitCard,
cash;
bool get isCard =>
this == PaymentType.creditCard ||
this == PaymentType.debitCard;
}
注意点:
- 複雑な条件分岐はメソッドやゲッターにまとめることで可読性が向上します
- 値の検証は型安全な方法で行うべきです
3.3 Map/Listでの使用
enum UserRole {
admin,
user,
guest;
static final Map<UserRole, String> permissions = {
UserRole.admin: 'full',
UserRole.user: 'limited',
UserRole.guest: 'readonly',
};
String get permission => permissions[this] ?? 'none';
}
注意点:
- Mapのキーとしてenumを使用する場合、すべての値をカバーすることを推奨します
- 静的な(static)マップを使用する場合は
final
にすることを推奨します
4. パフォーマンスと最適化
4.1 メモリ使用
enum CacheStrategy {
memory,
disk,
network;
// 静的なマップは一度だけ作成されます
static final Map<CacheStrategy, int> _timeouts = {
CacheStrategy.memory: 60,
CacheStrategy.disk: 3600,
CacheStrategy.network: 0,
};
int get timeout => _timeouts[this]!;
}
注意点:
- enumはシングルトンとして実装されます
- 静的なデータ構造は慎重に使用してください
- メモリ使用量を考慮してフィールドを設計してください
4.2 比較とパフォーマンス
enum Size {
small,
medium,
large
}
// 推奨される比較方法
void compare(Size size) {
if (size == Size.small) { // 直接比較
// ...
}
}
// 避けるべき比較方法
void compareString(Size size) {
if (size.toString() == 'Size.small') { // 文字列比較は避ける
// ...
}
}
注意点:
- enum値の直接比較は高速です
- 文字列比較は避けてください
-
index
による比較は避けてください
5. エラー処理とバリデーション
5.1 値の検証
enum ValidationStatus {
valid,
invalid,
pending;
bool get isValid => this == ValidationStatus.valid;
void validateOrThrow() {
if (this == ValidationStatus.invalid) {
throw Exception('Validation failed');
}
}
}
注意点:
- 無効な状態の処理を明確に定義してください
- 例外を投げる場合は適切な例外クラスを使用してください
- バリデーションロジックは集中管理してください
5.2 安全な型変換
enum LogLevel {
debug,
info,
warning,
error;
static LogLevel fromString(String value) {
try {
return LogLevel.values.firstWhere(
(level) => level.name == value.toLowerCase()
);
} catch (e) {
return LogLevel.info; // デフォルト値を返す
}
}
}
注意点:
- 文字列からの変換は常に検証が必要です
- デフォルト値を適切に設定してください
- 変換失敗時の挙動を明確に定義してください