Kotlin 中infix,inline,noinline,crossinline ,refied 等的理解
程序员文章站
2024-03-21 17:32:52
...
1. infix 的作用
infix 标示的函数可以使用中缀表示法, 中缀表示法就是在写法上可以忽略 . 与 ()并且必须满足三个条件
- 必须是成员函数或者扩展函数
- 必须只有一个参数
- 其参数不能有可变参,不能默认值
使用注意事项:
- 先级低于 算数操作符 ,类型转换 ,rangeTo 操作符
- 先级高于 &&, || 等
infix 可以使语法写起来更接近英语,人类语言。 下面举个例子可以更形象的理解
Shifts this value left by the bitCount number of bits.
Note that only the five lowest-order bits of the bitCount are used as the shift distance.
The shift distance actually used is therefore always in the range 0..31.
public infix fun shl(bitCount: Int): Int
使用: 1 shl 2 也可以1.shl(2) 是等价的
- inline 内联函数
内联函数出现的背景:
高阶函数会带来运行时的效率问题,并且每一个函数都是一个对象,所以内存消耗的更多。
内联函数的优缺点:
但是inline 需要使用得当,建议用来修饰逻辑不复杂的函数,不存在递归的函数。否则会带来性能影响。
内联函数
inline fun <T> lock(lock:Lock, body: ()->T ): T {....}
3. noinline 禁用内联
在使用内联函数是如果希望某个参数不内敛,可以用 noinline 来限定
// 标识函数 b 不内敛
inline fun test(a:()->Unit, noinline b:()->B )
可以内联的labmda 表达式只能在内联函数的内部调用 或者作为可内敛的参数传递。
noinline 修饰的函数可以赋值给变量。
4.crossinline
crossinline 的作用是让被标记的lambda表达式不允许非局部返回。
非局部返回:
在 Kotlin 中,我们只能对具名或匿名函数使用正常的非限定的 return 来退出。 这意味着要退出一个 lambda 表达式,我们必须使用一个 标签, 并且在 lambda 表达式内部禁止使用裸 return, 因为 lambda 表达式不能跳出包含它的函数
非局部返回
fun hasZeros(ints: List<Int>): Boolean {
ints.forEach {
if (it == 0) return true // 从 hasZeros 返回
}
return false
}
局部返回:
inline fun inlined(block: () -> Unit) {
println("hi!")
}
fun foo() {
inlined {
return // OK:该 lambda 表达式是内联的
}
}
fun main() {
foo()
}
//不允许从 body()->Unit lambda表达式中直接跳出 f 函数
inline fun f(crossinline body: () -> Unit) {
val f = object: Runnable {
override fun run() = body()
}
// ……
}
4.refied 具体化的类型参数
fefied 作用: 它就是提供泛型类型推断的功能的,需要和inline结合一齐使用。
普通的函数(未标记为内联函数的)不能有具体化参数。 不具有运行时表示的类型(例如非具体化的类型参数或者类似于Nothing的虚构类型) 不能用作具体化的类型参数的实参。
实际使用举例:
inline fun <reified T:Activity> Activity.startKtxActivity(context:Context){
startActivity(Intent(context,T::class.java))
}
// 跳转到MainActivity
startKtxActivity<MainActivity>(this)