【Kotlin内联函数】

【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. 概念理解funTgetType():String{returnT::class.java.name// ❌ 编译错误Cannot retrieve the class of a type parameter}inline funreifiedTgetTypeName():String{returnT::class.java.name}// 输出println(getTypeNameString())// 输出java.lang.Stringprintln(getTypeNameInt())// 输出int 或 java.lang.Integer视上下文而定2. 实际开发中的应用2.1 简化 Intent 构造使用泛型实化可以避免手动传入 Class 类型。inlinefunreifiedTnewIntent(context:Context):Intent{returnIntent(context,T::class.java)}// 使用valintentnewIntentDetailActivity(context)startActivity(intent)2.2 网络请求封装如 Retrofit 协程如果没有 reified你就必须手动传入 Type 或 Class代码会变得冗长且不优雅inlinefunreifiedTapiCall(crossinlinecall:()-ResponseT):ResultT{returntry{valresponsecall()if(response.isSuccessful){Result.Success(response.body()!!)}else{Result.Error(Exception(API Error))}}catch(e:Exception){Result.Error(e)}}2.3 SharedPreferences 或数据库的通用读取器inlinefunreifiedTSharedPreferences.get(key:String,defaultValue:T):T{returnwhen(T::class){String::class-getString(key,defaultValueasString)asT Int::class-getInt(key,defaultValueasInt)asT Boolean::class-getBoolean(key,defaultValueasBoolean)asTelse-throwIllegalArgumentException(Unsupported type)}}2.4 ViewModel工厂简化简化 ViewModel 的获取过程避免重复传入 Class 对象。inlinefunreifiedT:ViewModelFragment.viewModelProvider(factory:ViewModelProvider.Factory):T{returnViewModelProvider(this,factory)[T::class.java]}publicinlinefunComponentActivity.viewModels(noinlineextrasProducer:(()-CreationExtras)?null,noinlinefactoryProducer:(()-Factory)?null):LazyVM{valfactoryPromisefactoryProducer?:{defaultViewModelProviderFactory}returnViewModelLazy(VM::class,{viewModelStore},factoryPromise,{extrasProducer?.invoke()?:this.defaultViewModelCreationExtras})}使用 nolinepublicinlinefunComponentActivity.viewModels(noinlineextrasProducer:(()-CreationExtras)?null,noinlinefactoryProducer:(()-Factory)?null):LazyVM{valfactoryPromisefactoryProducer?:{defaultViewModelProviderFactory}returnViewModelLazy(VM::class,{viewModelStore},factoryPromise,{extrasProducer?.invoke()?:this.defaultViewModelCreationExtras})}1.使用 nolineinline时作为参数传进来的 lambda 默认会被 “展开成代码”但是这里需要作为参数传递2.使用泛型实化是因为需要获取 VM 的具体类型