Answer
Overview
Dart (unlike Swift) does not have a built-in
text
guardGuard Pattern in Dart (Early Return)
dart// Swift's guard: // guard let user = getUser() else { return } // Dart equivalent — early return on invalid condition void processUser(User? user) { // Guard: exit early if user is null if (user == null) return; // Guard: exit early if not active if (!user.isActive) { print('User is not active'); return; } // Guard: exit early if missing email if (user.email.isEmpty) { throw ArgumentError('Email is required'); } // Happy path — no nesting needed print('Processing user: ${user.name}'); sendWelcomeEmail(user.email); }
Null-aware Guard with ?? and !
dartvoid fetchData(String? url) { // Guard with null coalescing final safeUrl = url ?? 'https://default.api.com // Guard with assertion (throws if null) final token = getToken()!; // Crashes if null — use carefully // Better: null check guard final token2 = getToken(); if (token2 == null) { print('No token — user not logged in'); return; } // token2 is String (non-null) here }
Guard with Pattern Matching (Dart 3)
dart// switch with guard clause using 'when' String describeAge(int age) { return switch (age) { < 0 => 'Invalid age', < 13 => 'Child', int n when n < 18 => 'Teenager ($n)', // Guard with 'when' int n when n < 65 => 'Adult ($n)', _ => 'Senior', }; }
Guard in Form Validation
dartString? validateEmail(String? value) { // Guard chain if (value == null || value.isEmpty) return 'Email is required'; if (!value.contains('@')) return 'Invalid email format'; if (!value.contains('.')) return 'Invalid domain'; return null; // Valid — no guard triggered } Future<void> loginUser(String email, String password) async { // Guard: validate before proceeding final emailError = validateEmail(email); if (emailError != null) throw ArgumentError(emailError); if (password.length < 8) throw ArgumentError('Password too short'); // Happy path await authService.login(email, password); }
Extension for Guard-like Syntax
dartextension GuardExtension<T> on T? { T guard(String errorMessage) { if (this == null) throw StateError(errorMessage); return this!; } } // Usage final user = getUser().guard('User not found'); final token = cache['token'].guard('Token missing');
Summary: Dart doesn't have
keyword, but the same pattern is achieved with earlytextguard/textreturnon invalid conditions. Always put guard conditions at the top of a function — this avoids deep nesting and keeps the "happy path" flat.textthrow