1.函数如果没有使用lambda作为参数,就不需要声明成内联
2.函数如果使用lambda作为参数,就需要声明成内联,如果不使用内联,在调用端会生成多个对象来完成lambda的调用,会造成性能的损耗
3.函数如果使用lambda作为参数,使用inline关键字声明为内联,相当于C++中的#define 宏定义,宏替换。会把函数直接替换到(main/调用处)没有任何函数开辟,对象开辟的损耗。
4.结论:如果函数有lambda参数,尽量使用内联inline关键字。这样内部会有优化,减少函数开辟,对象开辟的损耗。
/**
* You can edit, run, and share this code.
* play.kotlinlang.org
*/
fun main() {
//调用传参---第一种方式
//普通参数传入即可,针对在调用函数中的参数函数传入使用匿名函数,匿名方法的返回值作为最终的打印结果:
//输入传参在调用该方法时传入即login方法中传入参数 responseResult("login success",200),,在主函数中使用匿名函数传入参数,并实现这个函数后输出最终的打印结果
val info=login("kotlin","123456"){msg:String,code:Int->
"登录结果:$msg,$code" //隐式返回
}
println(info)
//调用传参---第二种方式
//符合正常逻辑的传参格式:login(username:String,password:String,responseResult:(String,Int)->String):String),这里第三个参数也是实现提,
val info2=login("kotlin","123456",{msg:String,code:Int->
"登录结果:$msg,$code" //隐式返回
})
println(info2)
//调用传参---第三种方式,类型推断的匿名函数
val info3=login("kotlin","123456",responseResult={msg:String,code:Int->
"登录结果:$msg,$code" //隐式返回
})
println(info3)
}
//模拟数据库SQLServer
const val USER_NAME_DB="kotlin"
const val USER_PWD_DB="123456"
//登录
/*
* responseResult:(String,Int)->Unit) 传入响应结果的参数,同时也是获取响应结果的函数
*
* TODO()//Nothing类型,出现问题,终止程序
*
* */
private inline fun login(username:String,password:String,responseResult:(String,Int)->String):String{
if(username==null||password==null){
TODO("账号密码为空")//Nothing类型,出现问题,终止程序
}
//登录校验
if(username.length>3&&password.length>3){
if(isLogin(username,password)){
//登录成功逻辑,以及处理登录成功后的业务
//登录成功后返回响应结果,调用参数中的responseResult:(String,Int)->Unit)
return responseResult("login success",200)
}else{
//登录失败逻辑,以及处理登录失败后的业务
//登录失败后返回响应结果,调用参数中的responseResult:(String,Int)->Unit)
return responseResult("login failed",444)
}
}else{
TODO("账号密码不符合规范")//Nothing类型,出现问题,终止程序
}
return ""
}
//登录校验
private fun isLogin(username:String,password:String):Boolean{
return if(username==USER_NAME_DB && password==USER_PWD_DB) true else false
}
执行结果
6.使用内联inline时,上面的函数不能使用在public类型的函数上,不然会报错:
Public-API inline function cannot access non-public-API 'private fun isLogin(username: String, password: String): Boolean defined in root package in file File.kt'
公有 API 内联函数的限制
当⼀个内联函数是 public 或 protected 而不是 private 或 internal 声明的⼀部分时,就会认为它是⼀个模块级的公有 API。可以在其他模块中调用它,并且也可以在调用处内联这样的调用。
这带来了⼀些由模块做这样变更时导致的⼆进制兼容的⻛险⸺声明⼀个内联函数但调用它的模块在它修改后并没有重新编译。(A 调用了内联函数B,然后B修改了,A的调用处是不会重新编译的)
为了消除这种由非公有 API 变更引⼊的不兼容的风险,公有 API 内联函数体内不允许使用非公有声明,即,不允许使用private 与 internal 声明以及其部件。
结论:使用内联的函数体内不允许使用private 与 internal 声明以及其部件
修改如下:改变函数体内方法为公有或者将内联函数修改为 private 或 internal
或者: