Kotlin 中infix,inline,noinline,crossinline ,refied 等的理解

Posted bug樱樱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin 中infix,inline,noinline,crossinline ,refied 等的理解相关的知识,希望对你有一定的参考价值。

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)

以上是关于Kotlin 中infix,inline,noinline,crossinline ,refied 等的理解的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin扩展函数 ② ( 扩展属性 | 为可空类型定义扩展函数 | 使用 infix 关键字修饰单个参数扩展函数的简略写法 )

Kotlin扩展函数总结 ★ ( 超类扩展函数 | 私有扩展函数 | 泛型扩展函数 | 扩展属性 | 定义扩展文件 | infix 关键字用法 | 重命名扩展函数 | 标准库扩展函数 )

Kotlin扩展函数总结 ★ ( 超类扩展函数 | 私有扩展函数 | 泛型扩展函数 | 扩展属性 | 定义扩展文件 | infix 关键字用法 | 重命名扩展函数 | 标准库扩展函数 )

kotlin函数

kotlin函数

Kotlin:你必须要知道的 inline-noinline-crossinline