欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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) 是等价的

  1. 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)