Kotlin basics

Defining variable constants

In Kotlin, variables are defined differently from Java in the following ways:

  • Different placement: In Kotlin, data types are placed after variables and separated by colons (:), just the opposite of Java.
  • Variables and constants need keywords: in Kotlin, variables need to start with var and constants need to start with val.
  • Data type initials: In Kotlin, data types begin with an uppercase letter, whereas in Java, the names of complex data types, such as classes and interfaces, are generally capitalized.
  • If the variable is not initialized when it is defined, the data type must be specified. If the variable or constant is initialized when it is defined, the data type may not be specified. The Kotlin compiler automatically deduces the data type from the value to the right of the equal sign.
	private var m: Int = 30 // Define variables
	private val n: Int = 20 // Define constants with immutable values
	private var k = 40 // Automatically derive the data type of the variable
	private val a = 10 // Automatically derive the data type of the constant
Copy the code

** Lazy initialization of properties and variables: ** Generally, properties declared as non-null types must be initialized in constructors. However, this is often inconvenient. For example, properties can be initialized through dependency injection or in the setup method of a unit test. In this case, you cannot provide a non-empty initializer inside the constructor. But you still want to avoid null detection when referencing this property in the class body. To handle this, you can mark the property with the Lateinit modifier:

lateinit var name: String // Non-empty attributes delay initialization
Copy the code

Define a function

In Kotlin, the function definition uses the fun keyword, and the argument format is parameter: type, and finally the function return value type, as follows:

fun add(a:Int,b:Int):Int{
    return a+b
}
Copy the code

If the function returns no value, it can return Unit or nothing at all (omitting Unit) :

fun printSum(a:Int,b:Int){
    println("sum = ${a+b}")}Copy the code

Underlying data types

In Kotlin, everything is an object, in the sense that we can call member functions and properties on any variable. Some types can have special internal representations — for example, numbers, characters, and booleans can be represented as native type values at run time, but look like normal classes to the user. In this section, we describe the basic types used in Kotlin: numbers, characters, Booleans, arrays, and strings.

Numeric types

Kotlin provides a set of built-in types that represent numbers. For integers, there are four types of different sizes, so the range of values is different.

type Byte size (Bytes) Size (Bits) The minimum value The maximum
Byte 1 8 – 128. 127
Short 2 16 – 32768. 32727
Int 4 32 – 2 ^ 31 2 ^ 31-1
Long 8 64 – 2 ^ 63 2 ^ 63-1

For floating-point numbers, Kotlin provides Float and Double types. Float is single precision and Double is Double precision.

type Size (bits) The number of significant digital bits Exponential bit Decimal number
Float 32 24 8 6 to 7
Double 64 53 11 15 to 16

For variables initialized as decimals, the compiler will infer that they are of type Double. To specify a value explicitly as a Float type, add an f or f suffix. If such a value contains more than 6 to 7 decimal digits, it is rounded.

Type conversion: Implicit conversion is possible in Java. A type with a large value can be converted to a type with a small value, but this often results in loss of precision. In Kotlin, due to different representations, smaller types are not subtypes of larger types. This means that we cannot assign a Byte value to an Int variable without an explicit conversion. Each data type has the following methods, which can be converted to other types:

toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
Copy the code

Character types

In Kotlin, character types are represented by Char, but unlike Java, characters cannot be treated as numbers directly (Char.toint () can be converted by display); Char must be enclosed in single quotes’. For example, ordinary characters ‘0’, ‘a’, character literals enclosed in single quotes: ‘1’. Special characters can be escaped with backslashes. These escape sequences are supported: \t, \b, \n, \r, \’, \”, \\ and $.

 fun check(c:Char){
     if (c==1) {// Failed to compile}}fun check(c:Char){
     if (c=='1') {// Compilation succeeded}}Copy the code

Boolean type

Boolean is represented by Boolean type and has two values: true and false.

Empty reference booleans will be boxed if needed.

The built-in Boolean operations are:

  • ||– logic or
  • &&– logic and
  • !Non – logic

An array of

Arrays are represented in Kotlin using the Array class, which defines the get and set functions (which convert to [] according to operator overloading conventions) and the size property, as well as some other useful member functions:

class Array<T> private constructor() {
    val size: Int
    operator fun get(index: Int): T
    operator fun set(index: Int, value: T): Unit

    operator fun iterator(a): Iterator<T>
    / /...
}
Copy the code

We can use the library function arrayOf() to create an array and pass the element values to it, so arrayOf(1, 2, 3) creates an array [1, 2, 3]. Alternatively, the library function arrayOfNulls() can be used to create an array of a specified size with all elements empty.

Another option is to use an Array constructor that takes an Array size and a function argument that returns the initial value of each element of the given index:

/ / create a Array < String > initialized to [" 0 ", "1", "4", "9", "16"]
val asc = Array(5) { i -> (i * i).toString() }
asc.forEach { println(it) }
// arrayOf can be used to define arrays that store arbitrary values
var arr1 = arrayOf(1.2.3."hello")
println(arr1[3])

// Use arrayOfNulls to define fixed-length arrays
var arr2 = arrayOfNulls<Int> (10)
println(String.format("The length of the arR2 array is %d", arr2.size))
println("The length of arR2 array is :".plus(arr2.size))

// Use the Array constructor to define arrays and initialize the values of each Array element
var arr3 = Array(10) { i -> (i * i).toString() }
for (i in arr3.indices) {
   println(String.format("The %d element of array arr3 has the value :%s", (i + 1), arr3[i]))
}
println(arr3[9])

// Use intArrayOf, shortArrayOf and other functions to define arrays of the specified type
var arr4 = intArrayOf(10.2.30.40)
for (i in arr4.indices) {
   println(String.format("arr4[%d]==%d ,", i, arr4[i]))
}

Copy the code

In Kotlin, arrays are invariant. This means Kotlin won’t let us assign Array

to Array

to prevent possible runtime failures

string

In Kotlin, String is used to represent the String type, and there are two types of strings:

  • Ordinary string This string is similar to Ja. You can add an escape character to the string, for example\nWill replace the string after the escape character to the next line, which needs to be enclosed in double quotes.
  • Raw string: This type of string cannot be escaped. If the string has a format, such as a newline, it can be written to the string. This string needs to be placed in three quote pairs
 // A normal string, just like Java
 var s1 = "HELLO \nWORLD \n"
 // Preserve the source format string. No escape characters can be used
 var s2 = """ HELLO WORLD ARE YOU OK""".trimMargin()
 println(s1.plus(s2))
Copy the code

String template

String literals can contain template expressions, which are little pieces of code that evaluate and merge the results into the string. The template expression starts with a dollar character ($) and consists of a simple name:

val i = 10
println("i = $i") // output "I = 10"
Copy the code

Target platform: JVMRunning on kotlin v. 1.5.31

Or any expression enclosed in curly braces:

val s = "abc"
println("$s.length is ${s.length}") Abc.length is 3
Copy the code

Target platform: JVMRunning on kotlin v. 1.5.31

Templates are supported inside both raw and escaped strings. If you need to represent the literal $character in a raw string (which does not support backslash escape), you can use the following syntax:

val price = "" "The ${'$'}9.99 "" "
Copy the code

Control flow: if, when, for, while

If expression

In Kotlin, the if statement itself is an expression that returns a value, so Kotlin does not need to provide the ternary operator (condition? Then: else). Because the ordinary if will do the job.

   // Traditional usage
    var a = 20
    var b = 30
    var min = 0
    if (a > b) {
        println("The smaller value of a and B is 1:b=$b")}else {
        println("The smaller value of a and B is 2:a=$a")
    }
    a = 40
    b = 30
    if (a > b) min = b
    println("The smaller value of a and B is 3:a=$a,b=$b,min=$min")

    a = 50
    b = 40
    // Expression usage
    min = if (a > b) b else a
    println("The smaller value of a and B is 4:a=$a,b=$b,min=$min")
    a = 90
    b = 100
    min = if (a > b) {
        b / / the return value
    } else {
        a / / the return value
    }
    println("The smaller value of a and B is 5: A =$a,b=$b,min=$min")
Copy the code

When statement

In Kotlin, when replaces the SWITCH statement put in C. The standard when statement is used as follows:

var x = 1
when (x) {
    1 -> println("x==1")
    2 -> println("x==2")
    else -> {
        println("x is neither 1 or 2")
        println("end")}}Copy the code

When using the WHEN statement, note the following:

  • The WHEN statement looks for the first branch that meets the criteria based on the value passed in (x in this case), and then executes the branch.
  • If there are more than ten words in the branch, use {… }
  • A branch that satisfies this condition automatically terminates the when statement, so there is no need to add a break to each case statement as in the switch statement

When, like if, can be used as either a statement or an expression. In the latter case, the last expression of the first satisfying branch of the WHEN statement is the return value of the WHEN expression.

 // when is used as an expression
 var x = 1
 var m = when (x) {
     1 -> 20
     2 -> 30
     else -> 50
 }
 println("The value of m is:$m") // The value of m is :20
Copy the code

If none of the other branches meet the criteria, the else branch will be evaluated. If when is used as an expression, there must be an else branch, unless the compiler can detect that all possible cases have been covered [for enum class entries and sealed class subtypes, for example]. If many branches need to be treated in the same way, you can group multiple branch conditions together, separated by commas:

// If multiple conditions are met, separate the conditions with ","
when (x) {
     1.2.3 -> println("Meet the conditions")
     else -> println("Not eligible")}Copy the code

If there are too many conditions to execute the same code, or enumeration is not possible, you can use the in keyword to determine a range, as follows:

// Use the in keyword
var n = 25
when (n) {
    in 1.10. -> println("Not eligible")
    in 11.20. -> println("Meet the conditions")
    / /! In means not in this range
    !in 30.60. -> println("hello world")
    else -> println("Condition unknown")}Copy the code

It can also detect whether a value is (is) or not (! Is) a value of a specific type. Note: Thanks to smart conversions, you can access methods and properties of this type without any additional detection.

fun hasPrefix(x: Any) = when(x) {
    is String -> x.startsWith("prefix")
    else -> false
}
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

The branching condition in WHEN can be not just a constant, but any expression: for example, the following code branching condition is a function

The branching condition in when can be a constant and can be any expression. For example, the following code branching condition is a function.
var k = 5
when (k) {
	getValue(2) -> println("Meet the conditions")
	getValue(4) -> println("The condition is not met.")
	else -> println("Condition unknown")}private fun getValue(num: Int): Int {
    return num * num
}

Copy the code

The for loop

In Kotlin, the for loop can enumerate elements in a collection directly or by collection index.

var list = arrayListOf(1.2.3.4.5)
// The following syntax uses an iterator to enumerate all elements in a collection.
for (i in list) println("The for loop prints the collection information using iterators:$i")
var arr = intArrayOf(6.7.8.9.10)
for (i: Int in arr) println("The for loop prints the array information using iterators:$i")
// Enumerates the element values in an array using an index.
for (i in list.indices) {
    println("Enumerate element values with index values list[$i] =${list[i]}")}// It can also be abbreviated as follows
for ((index, value) in list.withIndex()) println("Enumerate element values list[$index] =$value")
Copy the code

The while loop

The while loop in Kotlin is the same as the while loop in Java. It is also divided into while, do… while

var i = 0
while (i++ < 10) println("While loop, I =$i")
do {
    if (i % 3= =0)
        println("Do while loop I =$i")
    if (i == 6)
        continue
    println(i)
    if (i == 5)
       break
} while (--i > 0)
Copy the code

In the do… Continue and break are used in the while loop, and can also be used in the for loop. Continue is to ignore all sentences following the current loop continue and continue from the next loop. Break is to terminate the loop and break out of the loop. This is exactly the same with Java.