kotlin中的内联函数笔记

582 阅读1分钟
原文链接: songsongtao.github.io

内联函数是指用inline关键字修饰的函数。在类内定义的函数被默认成内联函数。内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。

内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理。—— 百度百科

我个人认为其实就是把函数中的函数体提出来直接执行,减少了方法的进栈和出栈

准备

在使用内联函数之前需要了解kotlin中的泛型(与java类似)

lambda表达式 (Int) -> Unit输入是Int类型返回结果是空

我一开始也是一头雾水,现在算是一知半解

let

  • 源码
/**
 * Calls the specified function [block] with `this` value as its argument and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}
  • 使用
val block: (String) -> Int = {
     println(it)
     it.length
}
//对象调用函数且函数的参数是其本身(it),返回函数的结果
val let = "abc".let(block)
println("let:$let")
//控制台打印结果
abc
let:3

repeat

  • 源码
/**
 * Executes the given function [action] specified number of [times].
 *
 * A zero-based index of current iteration is passed as a parameter to [action].
 */
@kotlin.internal.InlineOnly
public inline fun repeat(times: Int, action: (Int) -> Unit) {
    contract { callsInPlace(action) }
    for (index in 0..times - 1) {
        action(index)
    }
}
  • 使用
val action: (Int) -> Unit = {
	println(it)
}
//参数(函数执行的次数,执行的函数)
repeat(3, action)
//打印结果
0
1
2

with

  • 源码
/**
 * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}
  • 使用
val block: String.() -> Int = {
	println(this)
	println(toUpperCase())
	length
}
//参数(对象,执行的函数(函数的参数是对象可执行的方法和属性 T.))返回函数的结果
val with = with("def", block)
println("with:$with")
//打印结果
def
DEF
with:3

run

  • 源码
/**
 * Calls the specified function [block] with `this` value as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}
  • 使用

可以看出和with类似,只是调用方式不一样