内联函数关键字
1.inline
2.noinline
3.crossinline
inline 是Kotlin 修饰方法的关键字。
noinline ,crossinline 是配合带有inline 方法修饰参数的关键字。
用法 并且 分析
inline
内联函数写法
内联函数相当于在该函数内,在调用另一个函数,某些需要开发者自己实现的功能,我只需传入固定好的参数,可根据需求定义返回值。
在sun函数前后处理一些固定的逻辑处理。
inline fun addUp(a: Int, b: Int, sum: (sum: Int) -> Unit) {
println("内联函数 sum 执行前。")
sum(a + b)
println("内联函数 sum 执行后。")
}
Java 调用内联函数写法
方法中最后一个参数就是平常写的回调。
Function1 第一个泛型是传入的参数类型,第二个是返回值类型。Kolitn 中 Unit 等同于Java void。
如果参数是多个 Function1 - Function21 针对参数个数自行创建。
如果超过21一个参数,那你就要考虑自己的方法是不是定义的有问题了,可拆分,Kotlin 中支持多个代码块参数。
结论 inline 在Java用法等同于Java 的回调。
TestInLineKt.addUp(10, 20, new Function1() {
@Override
public Unit invoke(Integer integer) {
System.out.println("内联函数 sum 执行结果。$it");
return null;
}
});
Kotlin 调用内联函数
调用方法,最后一个参数如果是代码块参数,可以写在小括号外面。
fun main(args: Array) {
val a = 10
valb = 20
addUp(a, b) {
println("内联函数 sum 执行结果。$it")
}
}
noinline
ps:内联函数在字节码中会进行优化,将整个内联函数全部放到调用地方,等同于没有调用方法,在运行过程中减少了入栈出栈的过程。
等同于写法
fun main(args: Array) {
val a = 10
val b = 20
println("内联函数 sum 执行前。")
var sum = a + b
println("内联函数 sum 执行结果。$sum")
println("内联函数 sum 执行后。")
}
上面案例只写了内联函数中只包含一个代码块参数。
如果需要将内联代码块,传递个另一个没有 inline 修饰的方法将会提示错误。
需要添加 noinline 参数修饰,也就意味着这个参数将不会被编译成字节码的时候优化。
inline fun addUp(a: Int, b: Int, noinline sum: (sum: Int) -> Unit) {
println("内联函数 sum 执行前。")
check(sum)
println("内联函数 sum 执行后。")
}
fun check(sum: (i: Int) -> Unit) {
println("另一个内联函数。")
sum(20)
}
crossinline
在代码中任何位置都可以写 return 关键字,但是在内联函数中经过jvm优化整个方法会被复制到调用的地方包括return,这就造成了下面方法无法运行。
在addUp代码块中添加 return 关键字运行。
fun main(args: Array) {
val a = 10
val b = 20
println("调用内联函数执行前。")
addUp(a, b) {
println("内联方法 sum 执行结果。$it")
return
}
println("调用内联函数执行后。")
}
inline fun addUp(a: Int, b: Int, sum: (sum: Int) -> Unit) {
println("内联方法 sum 执行前。")
sum(a + b)
println("内联方法 sum 执行后。")
}
打印结果:没有打印 “内联方法 sum 执行后。” 和 “调用内联函数执行后。” 代码方法在之前被终止。
调用内联函数执行前。
内联方法 sum 执行前。
内联方法 sum 执行结果。30
Process finished with exit code 0
解决办法
一. 指定 return 退出哪个函数。@ 后面跟内联函数的名称
return@addUp
二.在方法一中,如不指定 return 出哪个函数不会有语法检测,当在内联函数中添加 crossinline 关键字后,return 后面会强制指定退出当前内联函数。
fun main(args: Array) {
val a = 10
val b = 20
println("调用内联函数执行前。")
addUp(a, b) {
println("内联方法 sum 执行结果。$it")
return@addUp
}
println("调用内联函数执行后。")
}
inline fun addUp(a: Int, b: Int, crossinline sum: (sum: Int) -> Unit) {
println("内联方法 sum 执行前。")
sum(a + b)
println("内联方法 sum 执行后。")
}