In Kotlin, if and when statements are expressions that return a value. This allows for a more concise and functional
programming style with less cognitive complexity, because it results in fewer return points and fewer variable assignments in a function.
If both branches of an if statement end with a return statement, the if statement should be used instead as
an expression for a return statement.
If all branches of an exhaustive when statement end with a return statement, the when statement should be
used instead as an expression for a return statement. A when statement is exhaustive when it covers all elements of an enum
or features an else clause.
This change makes it easier to understand a function because it will reduce its complexity. This is because the function now contains fewer return points that the developer needs to keep track of.
Use the if statement as an expression for a return statement. Lift the return keyword from the end of the
if band else branch before the if keyword.
Use the when statement as an expression for a return statement. Lift the return keyword from the end of all
its case clauses before the when keyword.
fun returnIfElse(value: Int): String {
// ...
if (value >= 0) { // Noncompliant, every branch contains a return statement
return "positive"
} else {
return "negative"
}
}
fun returnIfElse(value: Int): String {
// ...
return if (value >= 0) { // Compliant
"positive"
} else {
"negative"
}
}
fun returnWhenElse(a: Float): Int {
// ...
when { // Noncompliant, every branch of exhaustive `when` contains a return statement
a < 0 -> return -1
a > 0 -> return 1
else -> return 0
}
}
fun returnWhenElse(a: Float): Int {
// ...
return when { // Compliant
a < 0 -> -1
a > 0 -> 1
else -> 0
}
}
enum class OneTwoThree {
ONE,
TWO,
THREE
}
fun returnWhenEnum(oneTwoThree: OneTwoThree): String {
// ...
when(oneTwoThree) { // Noncompliant, every branch of exhaustive `when` contains a return statement
OneTwoThree.ONE -> return "one"
OneTwoThree.TWO -> return "two"
OneTwoThree.THREE -> return "three"
}
}
fun returnWhenEnum(oneTwoThree: OneTwoThree): String {
// ...
return when(oneTwoThree) { // Compliant
OneTwoThree.ONE -> "one"
OneTwoThree.TWO -> "two"
OneTwoThree.THREE -> "three"
}
}
fun returnIfElseWithSideEffects(a: Float, b: Float): Int {
// ...
if (a < 0) { // Noncompliant, every branch contains a return statement
foo()
return -1
} else if (a > b) {
bar()
return 1
} else {
return 0
}
}
fun returnIfElseWithSideEffects(a: Float, b: Float): Int {
// ...
return if (a < 0) { // Compliant
foo()
-1
} else if (a > b) {
bar()
1
} else {
0
}
}