Kotlin Frequent Questions and Codes (Continuous Updates)

Posted by betazoid on Mon, 10 Jun 2019 23:50:16 +0200


Record Kotlin common problems and code.

4. Use when to express that multiple case s meet the criteria and the judgment should be complete.

Using Kotlin's when expression to judge that multiple case s are eligible, Java is

switch(x) {
case 1:
case 2:
break;
}

There's a pit here. There's a way:

fun check(value: Any?): String = when (value) {
    is Int, Float, Double -> {
        if (value == 0) "value For 0"
        else "value = $value"
    }
    else -> {
        "value Empty"
    }
}

This method is used to determine the input value, if it is Int, Float, Double type, then determine whether it is 0, if not return the string value is empty.

fun main(args: Array<String>) {
    println(check(1))
    println(check(11f))
    println(check(8.01))
    println(check(0))
}

The print result is as follows


... Unfortunately, it's totally different from what I thought. Why? Take a look at the compiled code.


The reason is not found. Only Int type has instanceof judgment, while the other two have not. Float and Double also have is judgment.

fun check(value: Any?): String = when (value) {
    is Int, is Float, is Double -> {
        if (value == 0) "value For 0"
        else "value = $value"
    }
    else -> {
        "value Empty"
    }
}

Let's look at the compiled code:


There are also printed results:


3. The difference between run, let, apply and with

run function


You can see that run is an extension function and has a return value. If the last line is returned as a return and Unit is returned by default, let's write an example.

data class User(val name: String = "jowan", val age: Int = 24)

fun main(args: Array<String>) {
    val user = User()
    // runUnit type is Unit
    val runUnit = user.run {
        println("runUnit:$this") // Print runUnit:User(name=jowan, age=24)
    }
    println("runUnit type:$runUnit") // Print runUnit type:kotlin.Unit
    // run type is User
    val run = user.run {
        println("run:$this") // Print run:User(name=jowan, age=24)
        User(age = 1)
    }
}

let function


As you can see, let is also an extension function. Like run function, it also has a return value. It returns the last line as a return and returns Unit by default. But unlike run, let has parameters and run does not:

data class User(val name: String = "jowan", val age: Int = 24)

fun main(args: Array<String>) {
    val user = User()
    // letUnit type is Unit
    val letUnit = user.let {
        println("letUnit:$it")
    }
    println("letUnit type:$letUnit")
    // let type is User
    val let = user.let {
        it ->
        println("let:$it")
        User(age = 2)
    }
}

apply function


apply

It can be seen that the application function is also an extension function, and also has a return value. It returns the object by default. The difference with run is that run returns the last line and apply returns the object:

data class User(val name: String = "jowan", val age: Int = 24)

fun main(args: Array<String>) {
    val user = User()
    // apply type is User
    val apply = user.apply {
        println("apply:$this") // Print apply:User(name=jowan, age=24)
    }
    apply.let {
        println("apply let:$it") // Print apply let:User(name=jowan, age=24)
    }
}

with function


with

It can be seen that the with function is not an extension function, which is similar to let and apply. It also has a return value. It returns the last line as a return, returns Unit by default, and can directly call methods and variables of the object.

data class User(val name: String = "jowan", val age: Int = 24)

fun main(args: Array<String>) {
    val user = User()
    // withUnit type is Unit
    val withUnit = with(user) {
        println("withUnit:$this") // Print withUnit:User(name=jowan, age=24)
    }
    // with type User
    val with = with(user) {
        println("with:$this, name:$name, age:$age") // Print with:User(name=jowan, age=24), name:jowan, age:24
        User(age = 111)
    }
    with.let {
        println("with let:$it") // Print with let:User(name=jowan, age=111)
    }
}

Summary

Function name Return value parameter Function type
run Closure return nothing spread function
let Closure return it spread function
apply this nothing spread function
with Closure return nothing Non-Extended Function
2. Setting default values

There is a problem that if the data obtained by Json is empty, it should be changed to the default value:

data class User(val name: String?, val age: Int?)

fun main(args: Array<String>) {
    var user = User(null, 23)
    println(user.name?.let { user.name } ?: "jowan")
}

Is it very troublesome to write in this way, so here we can write it as a method, so it is very convenient to call it:?

data class User(val name: String?, val age: Int?)

fun <T> T?.getDefault(default: T): T = this?.let { this } ?: default

fun main(args: Array<String>) {
    val (name, _) = User(null, 23)
    println(name.getDefault("jowan"))
    val (_, age2) = User("jowan", null)
    println(age2.getDefault(23))
}
1. Get the variable type (getJavaClass)


Use:: class.java to get the variable type, or. javaClass to get the type.

fun main(args: Array<String>) {
    val i = "str"
    val classJava = i::class.java
    println(classJava) // Print class java.lang.String
    val javaClass = i.javaClass
    println(javaClass) // Print class java.lang.String
}

Topics: Java JSON