Control Flow Statements
Control flow statements determine the order in which code executes. Dart provides various control structures for decision-making and iteration.
Conditional Statements
if-else
dart
int age = 18;
if (age >= 18) {
print('Adult');
} else {
print('Minor');
}
// if-else if-else
int score = 85;
if (score >= 90) {
print('A');
} else if (score >= 80) {
print('B');
} else if (score >= 70) {
print('C');
} else {
print('F');
}Conditional Expressions
Ternary Operator
dart
int age = 20;
String status = age >= 18 ? 'Adult' : 'Minor';
print(status); // AdultNull-aware Operator
dart
String? name;
String displayName = name ?? 'Guest';
print(displayName); // Guest
// Assign if null
name ??= 'Default Name';switch-case
dart
String grade = 'B';
switch (grade) {
case 'A':
print('Excellent!');
break;
case 'B':
print('Good!');
break;
case 'C':
print('Fair');
break;
default:
print('Invalid grade');
}
// Multiple cases
String day = 'Saturday';
switch (day) {
case 'Saturday':
case 'Sunday':
print('Weekend');
break;
default:
print('Weekday');
}Loops
for Loop
dart
// Standard for loop
for (int i = 0; i < 5; i++) {
print('Count: $i');
}
// For-in loop
List<String> fruits = ['apple', 'banana', 'orange'];
for (var fruit in fruits) {
print(fruit);
}
// forEach method
fruits.forEach((fruit) {
print(fruit);
});while Loop
dart
int count = 0;
while (count < 5) {
print('Count: $count');
count++;
}do-while Loop
dart
int num = 0;
do {
print('Number: $num');
num++;
} while (num < 5);Loop Control
break
Exits the loop immediately:
dart
for (int i = 0; i < 10; i++) {
if (i == 5) {
break; // Exit loop when i is 5
}
print(i);
}
// Output: 0, 1, 2, 3, 4continue
Skips the current iteration:
dart
for (int i = 0; i < 5; i++) {
if (i == 2) {
continue; // Skip when i is 2
}
print(i);
}
// Output: 0, 1, 3, 4Assert
Used for debugging to ensure conditions are true:
dart
int age = 15;
assert(age >= 18, 'Age must be 18 or older');
// Throws error in debug mode if condition is falsePattern Matching (Dart 3.0+)
Switch Expressions
dart
String grade = 'B';
String message = switch (grade) {
'A' => 'Excellent!',
'B' => 'Good!',
'C' => 'Fair',
_ => 'Invalid grade',
};
print(message); // Good!if-case
dart
Object value = 42;
if (value case int n when n > 0) {
print('Positive integer: $n');
}Collection Control Flow
Collection if
dart
bool includeZero = true;
List<int> numbers = [
1,
2,
if (includeZero) 0,
3,
];
print(numbers); // [1, 2, 0, 3]Collection for
dart
List<int> original = [1, 2, 3];
List<int> doubled = [
for (var num in original) num * 2,
];
print(doubled); // [2, 4, 6]Spread Operator
dart
List<int> list1 = [1, 2, 3];
List<int> list2 = [4, 5, 6];
List<int> combined = [...list1, ...list2];
print(combined); // [1, 2, 3, 4, 5, 6]
// Null-aware spread
List<int>? nullableList;
List<int> safe = [...?nullableList, 1, 2];
print(safe); // [1, 2]Best Practices
- Use switch expressions for cleaner code (Dart 3.0+)
- Prefer for-in over traditional for loops when iterating collections
- Use collection if/for for conditional list building
- Avoid deep nesting of if-else statements
- Use early returns to reduce nesting
Complete Example
dart
void main() {
// Grade calculator
List<int> scores = [85, 92, 78, 95, 88];
print('=== Grade Report ===');
for (int i = 0; i < scores.length; i++) {
int score = scores[i];
String grade = switch (score) {
>= 90 => 'A',
>= 80 => 'B',
>= 70 => 'C',
>= 60 => 'D',
_ => 'F',
};
print('Test ${i + 1}: $score - Grade $grade');
}
// Calculate average
int total = 0;
for (var score in scores) {
total += score;
}
double average = total / scores.length;
print('\nAverage: ${average.toStringAsFixed(2)}');
// Pass/Fail status
String status = average >= 70 ? 'PASS' : 'FAIL';
print('Status: $status');
// Filter passing scores
List<int> passingScores = [
for (var score in scores)
if (score >= 70) score,
];
print('\nPassing scores: $passingScores');
}