Use early returns and guard clauses to reduce nesting levels and improve code readability. When you have multiple conditional branches or error conditions, return early from the function rather than creating deeply nested if-else structures.
Use early returns and guard clauses to reduce nesting levels and improve code readability. When you have multiple conditional branches or error conditions, return early from the function rather than creating deeply nested if-else structures.
This pattern is especially beneficial when dealing with:
false
or emptyExample of improvement:
// Instead of deeply nested conditions:
fn process_data(data: &str) -> Result<String, Error> {
if !data.is_empty() {
if data.len() > 10 {
if data.starts_with("valid") {
// 4 levels of indentation - hard to read
Ok(data.to_uppercase())
} else {
Err(Error::InvalidPrefix)
}
} else {
Err(Error::TooShort)
}
} else {
Err(Error::Empty)
}
}
// Use early returns for cleaner code:
fn process_data(data: &str) -> Result<String, Error> {
if data.is_empty() {
return Err(Error::Empty);
}
if data.len() <= 10 {
return Err(Error::TooShort);
}
if !data.starts_with("valid") {
return Err(Error::InvalidPrefix);
}
Ok(data.to_uppercase())
}
This approach reduces cognitive load by handling edge cases upfront and keeping the main logic at a consistent indentation level. It also makes the function’s requirements and error conditions immediately clear to readers.
Enter the URL of a public GitHub repository