Conditional expressions
Both if and when can be used as expressions, producing a value instead of branching over statements. For their
statement forms, see Conditional statements.
val a = 7;
val b = 3;
val n = 2;
val max = if (a >= b) a else b;
print(max); // 7
val size = when (n) {
0 -> 'zero';
1, 2 -> 'small';
else -> 'big';
};
print(size); // small
An if expression always needs an else branch, and a when expression must be exhaustive; an else case makes it
exhaustive. Only the chosen arm evaluates. In an at-expression, a when expression is translated to the SQL
CASE WHEN ... THEN expression.
Value block arms
An arm can be a value block instead of a plain expression: zero or more statements followed by a trailing expression without a semicolon, which is the block's result.
function compute() = 21;
val cond = true;
val fallback = 0;
val n = 2;
val x = if (cond) {
val v = compute();
v * 2
} else fallback;
print(x); // 42
val y = when (n) {
0 -> 'zero';
1, 2 -> {
val s = 'small';
s + ':' + n
}
else -> 'big'
};
print(y); // small:2
A block arm has plain code-block semantics; it runs inline, in the enclosing function's frame:
-
Enclosing local variables are visible and assignable, and nullability analysis flows through the block.
-
returnreturns from the enclosing function. An arm that returns on all paths yields no value, and the conditional takes its result type from the other arms:val sign = if (n < 0) { return 'negative'; } else { 'non-negative' }; -
breakandcontinueinside a block arm bind to the enclosing loop. -
At-expression scope applies: attributes and the
$placeholder resolve inside a block arm of a collection-at projection.
The trailing expression without a semicolon is the block's value. A block with statements only is unit-typed, which a conditional arm can't be, unless it always returns.
Semicolons in a when expression are unchanged for expression arms: an expression arm is terminated by ;, and the
last case may omit it. A block arm ends at its closing } and takes no ;, like a block in a when statement.
Restrictions
- In expression positions with no enclosing body statement, that is, an at-expression body or a parameter or attribute
default value,
return,break, andcontinuecan't escape the block. The block itself is fine. - A value block can't be used in a global constant's expression, because its statements can't be validated as constant.
The same value-block form is available as a lambda body.
Value block arms are available from Rell 0.16.1.