【Kotlin内联函数】
文章目录
- 一. 理解何为内联
- 1. 没有内联的场景
- 2. 内联的场景
- 二. inline: 内联,将函数体插入调用处,提升性能
- 三. noinline:避免参数被内联
- 四. crossline:限制非局部返回
- 五. 内联函数的应用一:非局部返回
- 六. 内联函数应用二:具体化参数类型(泛型实化)
- 1. 概念理解
- 2. 实际开发中的应用
- 2.1 简化 Intent 构造
- 2.2 网络请求封装(如 Retrofit + 协程)
- 2.3 SharedPreferences 或数据库的通用读取器
- 2.4 ViewModel工厂简化
一. 理解何为内联
Kotlin中每声明一个Lambda表达式,就会在字节码中产生一个匿名类;额外增加开销
1. 没有内联的场景


会生成一个Function()类型的block类,然后通过invoke方法来执行
2. 内联的场景


二. inline: 内联,将函数体插入调用处,提升性能
Kotlin 中的一个关键字,用于优化 Lambda 表达式和高阶函数的性能。它主要用于减少因使用 Lambda 而产生的额外对象创建和方法调用开销
三. noinline:避免参数被内联

四. crossline:限制非局部返回

五. 内联函数的应用一:非局部返回
内联函数除了优化Lambda开销外,还支持非局部返回。
- 常规函数:无法局部返回

- 使用Lambda表达式:编译报错

- 第一种实现方式:内联函数

- 第二种方式:使用标签实现Lambda非局部返回

六. 内联函数应用二:具体化参数类型(泛型实化)
1. 概念理解
fun <T> getType(): String {return T::class.java.name // ❌ 编译错误:Cannot retrieve the class of a type parameter
}
inline fun <reified T> getTypeName(): String {return T::class.java.name
}
// 输出:
println(getTypeName<String>()) // 输出:java.lang.String
println(getTypeName<Int>()) // 输出:int 或 java.lang.Integer(视上下文而定)
2. 实际开发中的应用
2.1 简化 Intent 构造
使用泛型实化可以避免手动传入 Class 类型。
inline fun <reified T> newIntent(context: Context): Intent {return Intent(context, T::class.java)
}// 使用
val intent = newIntent<DetailActivity>(context)
startActivity(intent)
2.2 网络请求封装(如 Retrofit + 协程)
如果没有 reified,你就必须手动传入 Type 或 Class,代码会变得冗长且不优雅
inline fun <reified T> apiCall(crossinline call: () -> Response<T>): Result<T> {return try {val response = call()if (response.isSuccessful) {Result.Success(response.body()!!)} else {Result.Error(Exception("API Error"))}} catch (e: Exception) {Result.Error(e)}
}
2.3 SharedPreferences 或数据库的通用读取器
inline fun <reified T> SharedPreferences.get(key: String, defaultValue: T): T {return when (T::class) {String::class -> getString(key, defaultValue as String) as TInt::class -> getInt(key, defaultValue as Int) as TBoolean::class -> getBoolean(key, defaultValue as Boolean) as Telse -> throw IllegalArgumentException("Unsupported type")}
}
2.4 ViewModel工厂简化
简化 ViewModel 的获取过程,避免重复传入 Class 对象。
inline fun <reified T : ViewModel> Fragment.viewModelProvider(factory: ViewModelProvider.Factory): T {return ViewModelProvider(this, factory)[T::class.java]
}