Preface This blog is my study notes, if there is something wrong, please point out in the comment area, please forgive me

Kotlin’s Study Notes (9)

Reference article vernacular Kotlin

1. Inline functions

Speaking of inline functions we first need to talk about C++

Inline functions are one of the enhancements to C++ that reduce the running time of programs. Inlining occurs when an inlined function receives an indication from the compiler: the compiler replaces the function call statement with the function’s definition body, and this substitution occurs at compile time rather than program run time

1.1 Inline Meaning

  1. In Kotlin, functions are objects, and when you call a function, the associated object is created.

You see, that’s the cost of space!

  1. When you call a function, the virtual machine finds the location where you called the function. Then execute the function, and then go back to where you started.

You see, this is the cost of time!

Now, I put the code in the calling function directly where I called it, saving me the time to find the location of the calling function.

The normal way to call a function and the overhead


fun main(args: Array<String>) {

	println("Hello!)
	
	// The function call will look for the location of the function and return to it
	// This process is a kind of consumption
	shopImpl()
	
	
	fun shopImpl(a): Unit {
            println("hello world1")
            println("hello world2")}}Copy the code

Mark the fun shopImpl() function inline inline Inline Fun shopImpl(), and something amazing happens. Your code looks like this:

fun main(args: Array<String>) {

	println("Hello!)
	
	// Let's continue calling the shopImpl function
	shopImpl()
	
	// But instead of looking for the shopImpl function,
	// The contents of the shopImpl function are directly here without looking for calls
	// The compiler has already done this for us
	
	println("hello world1")
        println("hello world2")...inline fun shopImpl(a): Unit {
        println("hello world1")
        println("hello world2")}}Copy the code

Let’s finish by looking at two images of the difference between a normal call and a compiled inline function call

Ordinary call mode

Screenshot of an inline function call

1.2 Definition and invocation of inline functions

As we already know from 1.1, we only need to add the inline keyword in the header of the function

The problem

In Kotlin, functions are objects, and we can pass functions as arguments to functions. So the question is, what if the parameters in our inline function have functions? Is this function inline?

The answer

When a function is inlined and its arguments are also functions or lambda functions, the functions in the default arguments are also inlined by default


// The shopImpl function is an inline function
// The lambda function printString is also inlined by default

inline fun shopImpl(printString:(a:String) - >Unit): Unit {
    println("hello world 1")
    println("hello world 2")}// We can also add the noinline modifier before lambda if the function is not inline

inline fun shopImpl(noinline printString:(a:String) - >Unit): Unit {
    println("hello world 1")
    println("hello world 2")}Copy the code

2. Inline functions and returns

In Kotlin, return can only be used for named or anonymous functions, allowing the function to complete execution. For lambda expressions, you cannot use return directly

/** * We use the return + @ method name tag to end the current lambda function */
fun main(args: Array<String>) {
    println("start")
    forItem({if(it==1)return@forItem else println(it)})
    println("end")}fun forItem(item: (i:Int) - >Unit) {
    var i = 0
    while (i++<5){
        item(i)
    }
}

Copy the code

The results

Start // Based on the print, we see that 1 is returned by 2, 3, 4, 5 endCopy the code

However, it does work fine if you use inline functions with returns


// We can use return in forItem without a tag

fun main(args: Array<String>) {
    println("start")
    forItem({if(it==1)return else println(it)})
    println("end")}// Set to inline function
//
inline fun forItem(item: (i:Int) - >Unit) {
    var i = 0
    while (i++<5){
        item(i)
    }
}

Copy the code

The results

start
Copy the code

In the case of an inline function, a lambda expression is just a piece of code at compile time, when you have a return in a lambda, This is equivalent to a return within the method you called. So in this example, the return terminates the main function without printing the end.

2.2 Inline Properties (since V1.1)

For properties, we’re going to have get, set methods that manipulate that property. Get and set are functions, we can identify them as inline functions:


val foo: Foo
    inline get() = Foo()

var bar: Bar
    get() =...inline set(v) { ... }

Copy the code

Or (getters and setters are inline)


inline var bar: Bar
    get() = ...
    set(v) { ... }

Copy the code

2.3 Specific type parameters

Sometimes we need to access a type passed to us as an argument:


fun <T> TreeNode.findParentOfType(clazz: Class<T>): T? {
    var p = parent
    while(p ! =null && !clazz.isInstance(p)) {
        p = p.parent
    }
    @Suppress("UNCHECKED_CAST")
    return p as T?
}

Copy the code

Here’s how we use it:

treeNode.findParentOfType(MyTreeNode::class.java)

But it’s not elegant. We expect it to look like this:

treeNode.findParentOfType()

So how do I write that? Inline functions support specific type parameter declarations reified as follows:

inline fun <reified T> TreeNode.findParentOfType(a): T? {
    var p = parent
    while(p ! =null && p !is T) {
        p = p.parent
    }
    return p as T?
}
Copy the code