8 Enum
8.1 What is an Enum?
An enum (short for “enumeration”) is a special data type that represents a fixed set of named constants. Think of it as a way to create a custom type that can only have specific, predefined values. This is similar to creating a restricted set of options that make your code more readable and less error-prone.
In Python, you might have used the Enum
class from the enum
module. In Dart, enums are built into the language and are even more powerful.
8.2 Basic Enum Syntax
Let’s start with a simple example:
// Defining a basic enum
enum WeatherCondition {
,
sunny,
cloudy,
rainy
snowy}
// Using the enum
void main() {
= WeatherCondition.sunny;
WeatherCondition today // Output: WeatherCondition.sunny
print(today);
// You can also use the .name property to get just the value name
.name); // Output: sunny
print(today}
8.3 Why Use Enums?
Enums solve several problems:
- Type Safety: Instead of using strings like “sunny” or “rainy” (which could be misspelled), you use predefined constants
- Code Clarity: Your code becomes self-documenting
- IDE Support: Your editor can autocomplete enum values
- Compile-time Checking: Typos are caught during compilation, not runtime
Compare these two approaches:
// Without enum (error-prone)
String getDiseaseRisk(String condition) {
if (condition == 'diabetis') { // Oops! Typo won't be caught
return 'High risk';
}
return 'Normal risk';
}
// With enum (safer)
enum MedicalCondition {
,
diabetes,
hypertension
normal}
String getDiseaseRisk(MedicalCondition condition) {
if (condition == MedicalCondition.diabetes) { // Typo would cause compile error
return 'High risk';
}
return 'Normal risk';
}
8.4 Enhanced Enums (Dart 2.17+)
Modern Dart supports enhanced enums, which can have fields, methods, and constructors. This is where Dart enums become really powerful:
enum ImageModality {
// Each enum value can have associated data
'X-Ray', 'XR', 2),
xray('CT Scan', 'CT', 3),
ct('MRI', 'MR', 4),
mri('Ultrasound', 'US', 2);
ultrasound(
// Enum can have fields
final String fullName;
final String abbreviation;
final int dimensionality;
// Enum can have constructors
const ImageModality(this.fullName, this.abbreviation, this.dimensionality);
// Enum can have methods
bool is3D() => dimensionality > 2;
// You can even have getters
String get description => '$fullName ($abbreviation)';
}
void main() {
var modality = ImageModality.ct;
.fullName); // Output: CT Scan
print(modality.is3D()); // Output: true
print(modality.description); // Output: CT Scan (CT)
print(modality}
8.5 Common Enum Patterns
8.5.1 1. Using Enums in Switch Statements
Dart’s exhaustiveness checking ensures you handle all cases:
enum Priority { low, medium, high, urgent }
String getWaitTime(Priority priority) {
switch (priority) {
case Priority.low:
return '2-3 days';
case Priority.medium:
return '1 day';
case Priority.high:
return '4-6 hours';
case Priority.urgent:
return 'Immediate';
// No default needed - Dart knows all cases are covered!
}
}
8.5.2 2. Iterating Over Enum Values
enum Department {
,
radiology,
cardiology,
neurology
emergency}
void main() {
// Get all enum values
for (var dept in Department.values) {
.name);
print(dept}
// Find enum by name
var dept = Department.values.byName('radiology');
// Output: Department.radiology
print(dept); }
8.5.3 3. Enum with Complex Logic
enum FindingStatus {
'No abnormalities detected', 0),
normal('Benign findings', 1),
benign('Requires follow-up', 2),
suspicious('Urgent review needed', 3);
malignant(
final String message;
final int severityLevel;
const FindingStatus(this.message, this.severityLevel);
bool get requiresAction => severityLevel >= 2;
static FindingStatus fromSeverity(int level) {
return FindingStatus.values.firstWhere(
=> status.severityLevel == level,
(status) : () => FindingStatus.normal,
orElse
);}
}
8.6 When to Use Enums
Enums are perfect for:
- Fixed Sets of Options: Days of the week, months, user roles
- State Management: Loading states, form validation states
- Configuration Options: Theme modes, language settings
- Medical/Scientific Classifications: Disease stages, test results categories
Here’s a practical Flutter example:
enum ConnectionState {
,
idle,
connecting,
connected,
disconnected
error;
bool get isActive => this == connected;
{
Widget toIcon() switch (this) {
case idle:
return Icon(Icons.wifi_off, color: Colors.grey);
case connecting:
return CircularProgressIndicator();
case connected:
return Icon(Icons.wifi, color: Colors.green);
case disconnected:
return Icon(Icons.wifi_off, color: Colors.red);
case error:
return Icon(Icons.error, color: Colors.red);
}
}
}
// Usage in a Flutter widget
class ConnectionIndicator extends StatelessWidget {
final ConnectionState state;
const ConnectionIndicator({required this.state});
@override
{
Widget build(BuildContext context) return state.toIcon();
}
}
8.7 Practice Exercise
Try creating an enum for a radiology reporting system:
// Create an enum called 'BIRADS' (Breast Imaging Reporting and Data System)
// It should have categories 0-6 with appropriate descriptions and recommendations
// Include methods for:
// - whether follow-up is needed
// - recommended action
// - risk percentage range
// Your code here...