Conditions and cycles
If expression
In Kotlin, if is an expression: it returns a value. Therefore, there is no need for ternary operators
val max = if (a > b) a else b
Copy the code
If branches can be blocks of code, in which case the final expression is the value of that block
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
Copy the code
When the expression
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")}}Copy the code
When can be used as either an expression or a statement. If it is treated as an expression, the value of the first eligible branch is the value of the entire expression; if used as a statement, individual branch values are ignored
If when is used as an expression, there must be an else branch, unless the compiler can detect that all possible cases have been overridden (such as enumeration classes)
You can use any expression, not just a constant, as a branching condition
when (x) {
s.toInt() -> print("s encodes x")
else -> print("s does not encode x")}Copy the code
You can also detect a value in (in) or not in (! In) an interval or set:
when (x) {
in 1.10. -> print("x is in the range")
in validNumbers -> print("x is valid")!in 10.20. -> print("x is outside the range")
else -> print("none of the above")}Copy the code
📢 when can also be used to replace if-else if chains. If no arguments are provided, all branch conditions are simple Boolean expressions, and a branch is executed when its condition is true:
when {
x.isOdd() -> print("x is odd")
y.isEven() -> print("y is even")
else -> print("x+y is odd")}Copy the code
Capture the subject of when into a variable using the following syntax
fun Request.getBody(a) =
when (val response = executeRequest()) {
is Success -> response.body
is HttpError -> throw HttpException(response.status)
}
Copy the code
Variables introduced into the when subject are limited to the scope of the WHEN subject
The For loop
The for loop can iterate over any object that provides an iterator
for (item in collection) print(item)
Copy the code
To iterate over numeric intervals, use interval expressions
fun main(a) {
for (i in 1.3.) {
println(i)
}
for (i in 6 downTo 0 step 2) {
println(i)
}
}
Copy the code
A for loop for an interval or array is compiled as an index-based loop that does not create iterators
Traversing an index of a group of numbers can be done this way
fun main(a) {
val array = arrayOf("a"."b"."c")
for (i in array.indices) {
println(array[i])
}
}
Copy the code
Or you can use the withIndex library function:
fun main(a) {
val array = arrayOf("a"."b"."c")
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")}}Copy the code
Return and jump
Three structured jumps: Return, break, and continue
Each of these expressions can be used as part of a larger expression:
val s = person.name ?: return
Copy the code
Break and Continue labels
Any expression in Kotlin can be marked with a tag. The format of the tag is an identifier followed by the @ symbol
- Jumps and ends the loop specified by the label
loop@ for (i in 1.100.) {
for (j in 1.100.) {
if(...)break@loop}}Copy the code
- Returns from a lambda expression
Without the label, as in 🌰, return directly to the caller of foo()
fun foo(a) {
listOf(1.2.3.4.5).forEach {
if (it == 3) return // non-local returns directly to the caller of foo()
print(it)
}
println("this point is unreachable")}Copy the code
If you want to return from a lambda expression, you can label it and qualify the return
fun foo(a) {
listOf(1.2.3.4.5).forEach lit@{
if (it == 3) return@lit // Local returns to the caller of the lambda expression -- the forEach loop
print(it)
}
print(" done with explicit label")}Copy the code
It is usually more convenient to use an implicit label because the label has the same name as the function that accepts the lambda
fun foo(a) {
listOf(1.2.3.4.5).forEach {
if (it == 3) return@forEach // Local returns to the caller of the lambda expression -- the forEach loop
print(it)
}
print(" done with implicit label")}Copy the code
Alternatively, we can replace lambda expressions with an anonymous function. A return statement inside an anonymous function is returned from the anonymous function itself
fun foo(a) {
listOf(1.2.3.4.5).forEach(fun(value: Int) {
if (value == 3) return // local returns to the caller of the anonymous function -- forEach loop
print(value)
})
print(" done with anonymous function")}Copy the code
The previous three examples are similar to the use of continue in a regular loop and do not have a direct equivalent of break, but can be simulated by adding another layer of nested lambda expressions and returning non-locally from them
fun foo(a) {
/ /?? â‘ Run
run loop@{
listOf(1.2.3.4.5).forEach {
if (it == 3) return@loop // Returns nonlocally from the lambda expression passed to run
print(it)
}
}
print(" done with nested loop")}Copy the code
(?????? When it comes to returning a value, the parser preferentially uses tag-qualified returns:
return@a 1
Copy the code
This means “return 1 to @ A”, not “return a labeled expression (@a 1)”.
abnormal
Try is an expression
Try is an expression, which means it can have a return value:
val a: Int? = try { input.toInt() } catch (e: NumberFormatException) { null }
Copy the code
The return value of a try- expression is either the last expression in a try block or (all) the last expression in a catch block. The contents of the finally block do not affect the result of the expression
B. abnormal
Kotlin has not been tested for any anomalies, which can be seen in Effective Java, 3rd edition, Article 77:
A few small program tests suggest that exception specifications improve both developer productivity and code quality, but experience with large software projects suggests a different conclusion — reduced productivity and little or no improvement in code quality.
Nothing type
In Kotlin, a throw is an expression, which is of type Nothing. This type has no value and is used to mark code locations that can never be reached.
val s = person.name ?: throw IllegalArgumentException("Name required")
Copy the code
You can use Nothing to mark a function that never returns
val s = person.name ?: fail("Name required")
println(s) // it is known here that "s" is initialized
Copy the code
When you call this function, the compiler knows that execution will stop after the call
question list
- ?? Run, run, run
- ?? â‘¡ Where is the return value used
other
If you are new to Kotlin and want to review the knowledge quickly, you can check it out here.
Official Chinese document:
- www.kotlincn.net/docs/refere…
- book.kotlincn.net/
Run Kotlin online:
- www.bejson.com/runcode/kot…
- play.kotlinlang.org/