What is the role of inline functions in Kotlin?

Android ask every day, small Jucheng River, big Jucheng river.

For more information, visit GitHub Android daily interview summary.

Note: the following is my personal understanding and sorting with your answers, and the latest answers are updated from time to time.

In the past, I forgot a lot of things because I learned Kotlin for a period of time (not used in actual development), but Kotlin's code actually looks no different from Java and feels almost the same. So don't think Kotlin is hard to learn.

First, what is the inline function?

Kotlin's inline function is one of kotlin's advanced features and is very simple to use.

Next, let me demonstrate it with practical operation;

public class Test {
    public static void main(String[] args) {
        System.out.println(sum(10)+sum(5));
    }

    private static int sum(int a){
        int sum=8;
        sum+=a;
        return sum;
    }
}

This is a piece of java code. It can't be simpler. It's repeated addition. Don't pay attention to logic. It's just for demonstration.

The same kotlin Code:

inline fun sum(a: Int): Int {
    var sum = 8
    sum += a
    return sum
}

fun main() {
    println(sum(10)+ sum(5))
}

Although it looks very concise at first glance, our focus is not here, but on the inline keyword. In order to facilitate everyone's study, I can turn it into the corresponding java code by checking the bytecode, which is convenient for everyone to better understand.

Before adding inline

After adding inline

Needless to say, kotlin automatically adds the method to the corresponding call at the compilation time, eliminating the method stack in and out of java.

PS: (don't think kotlin is so difficult. In fact, I'm learning and selling now, although I've seen some basics before, ha ha)

Let's expand our knowledge:

The following is from your answers. I can't understand the specific reasons, so I need to make up classes on weekends.

TODO

noinline

Make the original inline function parameter function not inline and retain the original data characteristics

If the parameter of an inline function contains a lambda expression, that is, the function parameter, then the formal parameter is also inline. For example:

inline fun test(inlined: () -> Unit) {...} There is a problem to note here. If the function parameter is called by other non inline functions inside the inline function, an error will be reported, as shown below:

noinline
 If the parameters of an inline function contain lambda Expression, that is, function parameter, so is the formal parameter inline , for example:
inline fun test(inlined: () -> Unit) {...}
There is a problem to note here. If the function parameter is called by other non inline functions inside the inline function, an error will be reported, as shown below:

To solve this problem, you must add a noinline modifier to the parameters of the inline function, which means that inline is prohibited and the characteristics of the original function are retained. Therefore, the correct writing of the test() method should be:

inline fun test(noinline inlined: () -> Unit) {
otherNoinlineMethod(inlined)
}

crossinline

Nonlocal return flag To prevent lamba expressions from directly returning inline functions Related knowledge points: as we all know, in kotlin, if there is a lambda expression in a function, it is not supported to exit the function directly through return, but only through return return@XXXinterface This way

First, let's understand a concept: nonlocal return. Let's take chestnuts for example:

fun test() {
innerFun {
//Return if you write this, an error will be reported. If you return nonlocally, you can exit the test() function directly.
return@innerFun //Return locally and exit the innerFun() function. Here, you must specify which function to exit and write it as return@test Will exit the test() function
}

//The following code will still execute
println("test...")
}
fun innerFun(a: () -> Unit) {
a()
}

My understanding of non local return is to return to the top-level function, as shown in the above code. By default, it cannot return directly, but inline functions can. So change it to the following:

fun test() {
innerFun {
return //For non local return, exit the test() function directly.
}
inline fun innerFun(a: () -> Unit) {
a()
}

That is, the function parameters of the inline function can be returned nonlocally when called, as shown above. Then the lambda parameter modified by crossinline can prohibit nonlocal return during inline function calls.

fun test() {
innerFun {
return //This will report an error here. You can only return@innerFun
}

//The following code will not be executed
println("test...")
}

inline fun innerFun(crossinline a: () -> Unit) {
a()
}

Materialized type parameter reified

In java, generic types cannot be used directly kotlin can use generic types directly

inline fun startActivity() {
startActivity(Intent(this, T::class.java))
}
When using, you can directly pass in generics, and the code is concise and clear:

Added by delmardata on Wed, 09 Feb 2022 23:31:26 +0200