You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/md/kotlin.core/expressions.md
+92-43Lines changed: 92 additions & 43 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,7 +15,7 @@ As all expressions are valid [statements][Statements], standalone expressions ma
15
15
An expression is used as an expression, if it is encountered in any position where a statement is not allowed, for example, as an operand to an operator or as an immediate argument for a function call.
16
16
An expression is used as a statement if it is encountered in any position where a statement is allowed.
17
17
18
-
Some expressions are only allowed to be used as statements, if certain restrictions are met; this may affect the semantics, the compile-time type information or/and the safety of these expressions.
18
+
Some expressions are allowed to be used as statements, only if certain restrictions are met; this may affect the semantics, the compile-time type information or/and the safety of these expressions.
19
19
20
20
### Constant literals
21
21
@@ -75,12 +75,12 @@ Any of the decimal, hexadecimal or binary literals may be suffixed by the long l
75
75
An integer literal with the long literal mark has type `kotlin.Long`.
76
76
A literal without the mark has a special [integer literal type][Integer literal types] dependent on the value of the literal:
77
77
78
-
- If the value is greater than maximum `kotlin.Long` value (see [built-in integer types][Built-in integer types]), it is an illegal integer literal and a compiler error;
78
+
- If the value is greater than maximum `kotlin.Long` value (see [built-in integer types][Built-in integer types]), it is an illegal integer literal and should be a compile-time error;
79
79
- Otherwise, if the value is greater than maximum `kotlin.Int` value (see [built-in integer types][Built-in integer types]), it has type `kotlin.Long`;
80
-
- Otherwise, it has an integer literal type containing all the built-in integer types that are guaranteed to be able to represent this value.
80
+
- Otherwise, it has an integer literal type containing all the built-in integer types guaranteed to be able to represent this value.
81
81
82
-
> Note: for example, integer literal `0x01` has value $1$ and therefore has type $\LTS(\mathtt{kotlin.Byte}, \mathtt{kotlin.Short}, \mathtt{kotlin.Int}, \mathtt{kotlin.Long})$.
83
-
> Integer literal `70000` has value $70000$, which is not representable using types `kotlin.Byte` and `kotlin.Short` and therefore has type $\LTS(\mathtt{kotlin.Int}, \mathtt{kotlin.Long})$.
82
+
> Example: integer literal `0x01` has value $1$ and therefore has type $\LTS(\Byte, \Short, \Int, \Long)$.
83
+
> Integer literal `70000` has value $70000$, which is not representable using types `kotlin.Byte` and `kotlin.Short` and therefore has type $\LTS(\Int, \Long)$.
84
84
85
85
#### Real literals
86
86
@@ -187,8 +187,6 @@ All other situations mean that an exception is going to be propagated up the cal
187
187
188
188
The type of the try-expression is the [least upper bound][Least upper bound] of the types of the last expressions of the try body and the last expressions of all the catch blocks.
189
189
190
-
> Note: in some cases, the least upper bound is handled as described [here][The relations on types as constraints], from the point of view of type constraint system.
191
-
192
190
> Note: these rules mean the try-expression always may be used as an expression, as it always has a corresponding result value.
193
191
194
192
### Conditional expression
@@ -207,40 +205,40 @@ If the condition evaluates to `true`, the first branch (the *true branch*) is ev
207
205
The value of the resulting expression is the same as the value of the chosen branch.
208
206
209
207
The type of the resulting expression is the [least upper bound][Least upper bound] of the types of two branches, if both branches are present.
210
-
If either of the branches are omitted, the resulting conditional expression has type [`kotlin.Unit`][`kotlin.Unit`] and may used only as a statement.
211
-
212
-
Let's illustrate it with some examples:
208
+
If either of the branches are omitted, the resulting conditional expression has type [`kotlin.Unit`][`kotlin.Unit`] and may be used only as a statement.
213
209
214
-
```kotlin
215
-
// x has type kotlin.Int and value 1
216
-
val x = if(true) 1 else 2
217
-
// illegal, if expression without false branch cannot be used as an expression
218
-
val y = if(true) 1
219
-
```
210
+
>Example:
211
+
>
212
+
> ```kotlin
213
+
>// x has type kotlin.Int and value 1
214
+
>val x =if (true) 1else2
215
+
>// illegal, as if expression without false branch
216
+
>// cannot be used as an expression
217
+
>val y =if (true) 1
218
+
> ```
220
219
221
-
The type of the condition expression must be a subtype of `kotlin.Boolean`, otherwise it is an error.
220
+
The type of the condition expression must be a subtype of `kotlin.Boolean`, otherwise it isa compile-time error.
222
221
223
222
>Note:when used as expressions, conditional expressions are special w.r.t. operator precedence: they have the highest priority (the same asfor all primary expressions) when placed on the right side of any binary expression, but when placed on the left side, they have the lowest priority.
224
223
>For details, see Kotlin [grammar][Syntax grammar].
225
224
>
226
-
> For example:
225
+
>Example:
227
226
>
228
227
> ```kotlin
229
-
> x = if(true) 1 else 2
228
+
> x =if(true) 1else2
230
229
> ```
231
230
>is the same as
232
231
> ```kotlin
233
-
> x = (if(true) 1 else 2)
232
+
> x = (if(true) 1else2)
234
233
> ```
235
-
> while
234
+
>At the same time
236
235
> ```kotlin
237
-
> if(true) x = 1 else x = 2
236
+
>if(true) x =1else x =2
238
237
> ```
239
238
>is the same as
240
239
> ```kotlin
241
-
> if(true) (x = 1) else (x = 2)
240
+
>if(true) (x =1) else (x =2)
242
241
> ```
243
-
>
244
242
245
243
### When expression
246
244
@@ -256,7 +254,7 @@ The type of the condition expression must be a subtype of `kotlin.Boolean`, othe
256
254
:::
257
255
258
256
*When expression*is similar to a [conditional expression][Conditional expression] in that it allows one of several different [control structure bodies][Code blocks] (*cases*) to be evaluated, depending on some boolean conditions.
259
-
The key difference is exactly that a when expressions may include several different conditions with their corresponding control structure bodies.
257
+
The key difference is that a when expressions may include *several* different conditions with their corresponding control structure bodies.
260
258
When expression has two different forms: with bound value and without it.
261
259
262
260
**When expression without bound value** (the form where the expression enclosed in parentheses after the `when` keyword is absent) evaluates one of the different CSBs based on its condition from the *when entry*.
@@ -268,31 +266,79 @@ All remaining conditions and expressions are not evaluated.
268
266
The `else` condition is a special condition which evaluates to `true` if none of the branches above it evaluated to `true`.
269
267
The `else` condition **must** also be in the last when entry of when expression, otherwise it is a compile-time error.
270
268
271
-
> Note: informally, you can always replace the `else` condition with an always-`true` condition (e.g., boolean literal `true`) with no change to the resulting semantics.
269
+
>Note: informally, you can always replace the `else` condition with an always-`true` condition (e.g., boolean literal `true`) with no changes to the result of when expression.
272
270
273
-
**When expression with bound value** (the form where the expression enclosed in parentheses after the `when` keyword is present) are similar to the form without bound value, but use a different syntax for conditions.
274
-
In fact, it supports three different condition forms:
271
+
**When expression with bound value** (the form where the expression enclosed in parentheses after the `when` keyword is present) is similar to the form without bound value, but uses a different syntaxand semanticsfor conditions.
272
+
In fact, it supports four different condition forms:
275
273
276
274
-*Type test condition*: [type checking operator][Type-checking expression] followed by a type (`isT` or `!isT`).
277
275
The resulting condition is a [type check expression][Type-checking expression] of the form `boundValue isT` or `boundValue !isT`.
278
276
-*Contains test condition*: [containment operator][Containment-checking expression] followed by an expression (`inExpr` or `!inExpr`).
279
277
The resulting condition is a [containment check expression][Containment-checking expression] of the form `boundValue inExpr` or `boundValue !inExpr`.
280
-
- *Any other applicable expression* (`Expr`) besides the following.
The resulting condition is an [equality check][Equality expressions] of the form `boundValue ==Expr`.
285
280
-The `else` condition, which is a special condition which evaluates to `true` if none of the branches above it evaluated to `true`.
286
281
The `else` condition **must** also be in the last when entry of when expression, otherwise it is a compile-time error.
287
282
288
-
TODO([Kotlin 1.3+] break and continue in when)
289
-
290
283
>Note: the rule for"any other expression" means that if a when expression with bound value contains a boolean condition, this condition is**checked for equality** with the bound value, instead of being used directly forwhen entry selection.
291
284
292
-
TODO(Examples)
285
+
>Note:inKotlin version 1.3and earlier, simple (unlabeled) `break` and `continue` expressions were disallowed inwhen expressions.
286
+
287
+
The type of the resulting when expression is the [least upper bound][Least upper bound] of the types of all its entries.
288
+
Ifwhen expression isnot [exhaustive][Exhaustivewhen expressions], it has type [`kotlin.Unit`][`kotlin.Unit`] and may be used only as a statement.
293
289
294
-
The type of the resulting expression is the [least upper bound][Least upper bound] of the types of all its entries.
295
-
If the when expression is not [exhaustive][Exhaustive when expressions], it has type [`kotlin.Unit`][`kotlin.Unit`] and may only be used as a statement.
290
+
>Examples:
291
+
>
292
+
> ```kotlin
293
+
>val a =42
294
+
>val b =-1
295
+
>
296
+
>when {
297
+
> a == b -> {}
298
+
> a != b -> {}
299
+
> }
300
+
>
301
+
>// Error, as it is a non-exhaustive when expression
302
+
>val c =when {
303
+
> a == b -> {}
304
+
> a != b -> {}
305
+
> }
306
+
>
307
+
>val d =when {
308
+
> a == b -> {}
309
+
> a != b -> {}
310
+
>else-> {}
311
+
> }
312
+
>
313
+
>when {
314
+
> a == b || a != b -> {}
315
+
>42>0-> {}
316
+
> }
317
+
> ```
318
+
>
319
+
> ```kotlin
320
+
>val a =42
321
+
>val b =-1
322
+
>
323
+
>val l = (1..10).toList()
324
+
>
325
+
>when (a) {
326
+
>isInt, !isInt-> {}
327
+
>in l, !in l -> {}
328
+
> }
329
+
>
330
+
>// Error, as it is a non-exhaustive when expression
331
+
>val c =when (a) {
332
+
>isInt, !isInt-> {}
333
+
>in l, !in l -> {}
334
+
> }
335
+
>
336
+
>val d =when (a) {
337
+
>isInt, !isInt-> {}
338
+
>in l, !in l -> {}
339
+
>else-> {}
340
+
> }
341
+
> ```
296
342
297
343
#### Exhaustivewhen expressions
298
344
@@ -309,23 +355,26 @@ A when expression is called **_exhaustive_** if at least one of the following is
309
355
-The bound expression is of an [`enumclass`][Enumclassdeclaration] type and all its enumerated values are checked for equality using constant expression;
310
356
-The bound expression is of a [nullable type][Nullable types] $T?$ and one of the cases above is met for its non-nullable counterpart $T$ together with another condition which checks the bound value for equality with `null`.
311
357
312
-
For object types, the type test condition may be replaced with equality check with the object value:
358
+
Forobject types, the type test condition may be replaced with equality check with the object value.
359
+
360
+
>Note:if one were to override `equals` for an object type incorrectly (i.e., so that an objectis not equal to itself), it would break the exhaustiveness check.
361
+
>Such situations are considered to have undefined behaviour.
313
362
314
363
```kotlin
315
364
sealedclassBase
316
-
class Derived1(): Base()
317
-
object Derived2(): Base
365
+
classDerived1: Base()
366
+
object Derived2: Base()
318
367
319
-
...
320
368
val b:Base=...
321
-
... = when(b) {
369
+
370
+
val c =when(b) {
322
371
isDerived1->...
323
372
Derived2->...
324
373
// no else needed here
325
374
}
326
375
```
327
376
328
-
> Note: informally, an exhaustive when expression is guaranteed to evaluate one of its CSBs regardless of the specific when conditions.
377
+
>Informally: an exhaustive when expression is guaranteed to evaluate one of its CSBs regardless of the specific when conditions.
Copy file name to clipboardExpand all lines: docs/src/md/kotlin.core/type-system.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1014,6 +1014,8 @@ This normalization procedure, if finite, creates a *canonical* representation of
1014
1014
- if $A = (L_A..U_A)$ and $B = (L_B..U_B)$, $\LUB(A, B) = (\LUB(L_A, L_B)..\LUB(U_A, U_B))$
1015
1015
- if $A = (L_A..U_A)$ and $B$ is not flexible, $\LUB(A, B) = (\LUB(L_A, B)..\LUB(U_A, B))$
1016
1016
1017
+
> Important: in some cases, the least upper bound is handled as described [here][The relations on types as constraints], from the point of view of type constraint system.
1018
+
1017
1019
TODO(actual algorithm for computing LUB)
1018
1020
1019
1021
TODO(LUB for 3+ types)
@@ -1075,6 +1077,8 @@ This normalization procedure, if finite, creates a *canonical* representation of
1075
1077
- if $A = (L_A..U_A)$ and $B = (L_B..U_B)$, $\GLB(A, B) = (\GLB(L_A, L_B)..\GLB(U_A, U_B))$
1076
1078
- if $A = (L_A..U_A)$ and $B$ is not flexible, $\GLB(A, B) = (\GLB(L_A, B)..\GLB(U_A, B))$
1077
1079
1080
+
> Important: in some cases, the greatest lower bound is handled as described [here][The relations on types as constraints], from the point of view of type constraint system.
0 commit comments