A captured variable is a value made available beyond its immediate declaration context. Kotlin uses the term for a when subject bound inside the expression and for external variables retained by a lambda. section 2.3.3 section 5.1.4
Listing 2.14 Assigning the subject of a when to a variable
import ch02.colors.Color.* #1
fun measureColor() = ORANGE
fun getWarmthFromSensor() =
when (val color = measureColor()) { #2
RED, ORANGE, YELLOW -> "warm (red = ${color.r})" #3
GREEN -> "neutral (green = ${color.g})"
BLUE, INDIGO, VIOLET -> "cold (blue = ${color.b}"
}
Bind the result of measureColor() directly in the when expression. The variable remains scoped to the expression while its properties remain available in each branch. section 2.3.3
Use a captured when subject to avoid an unrelated variable in surrounding code. When the when result is assigned or returned, every possible path must produce a value; covering all enum constants or adding else satisfies exhaustiveness. section 2.3.3
Capturing variables in a lambda
fun printProblemCounts(responses: Collection<String>) { var clientErrors = 0 var serverErrors = 0 responses.forEach { if (it.startsWith("4")) clientErrors++ else if (it.startsWith("5")) serverErrors++ } println("$clientErrors client errors, $serverErrors server errors") } section 5.1.4
Unlike Java, Kotlin lambdas can capture and modify nonfinal local variables. A captured val is stored with the lambda; a captured var uses a wrapper so later executions can observe its updated value. Capturing can also affect Java interoperation: a lambda passed to a Java method may require a new object per call when it captures a surrounding value. section 5.1.4 section 5.2.1
