English
Summary
Conclusions
Every variable has a static type, even when inferred by the compiler, and val only prevents reference reassignment. Numeric types have limited ranges, so account for overflow and Double imprecision when choosing types and operation order. Kotlin does not implicitly widen Int to Long, and rounding rules must be chosen explicitly according to the problem's contract. Nullable types make a potentially absent value part of the contract: ?., ?:, and checks with smart casts handle it safely, while !! merely asserts that there is no null. == compares values, while === compares reference identity. if and when are expressions, so their results must be defined on every path, and branch boundaries are tested with neighboring values. Ranges, loops, break, continue, and labels determine traversal termination, which should be clear. A reliable program is checked using a table of boundary cases and a loop invariant, not one successful run.
Self-check questions
- Why does val not mean that every object is immutable?
- When must Int be widened to Long?
- How does null differ from an empty string?
- Why is !! not input validation?
- What conditions are required for a smart cast?
- How does == differ from ===?
- When is a range's right bound excluded?
- How can you formulate an accumulator loop's invariant?