一: 定义高阶函数
定义: 一个函数接收另一个函数作为参数 或者 返回值是另一个函数
函数类型: (String, Int) -> Unit
高阶函数:
fun example( fun : (String , Int) -> Unit) {
}
高阶函数调用方式:Lambda, 匿名函数,成员引用
Lambda: Lambda 表达式的最后一行代码会自动作为返回值
Kotlin:
public static int num1Andnum2(int num1, int num2 , Function operation){
int result = int (operation).invoke(num1,num2);
return result;
}
转化为Java支持的语法结构:
public static void main(){
int num1 = 80;
int num2 = 100;
int result = num1Andnum2(num1, num2, new Funciton(){
@Override
public Integer invoke (Integer n1, Integer n2){
retun n1+n2;
}
});
}
二:内联函数的作用(inline)
高阶函数实现原理:Lambda 表达式在底层被转换成了匿名类的实现方式。(每调用一次 Lambda 就会创建一个新的匿名类,造成额外的内存和性能开销)
内联函数:可以将Lambda表达式带来的运行时开销完全消除。
内联函数工作原理:将内联函数的代码在编译的时候自动替换到调用它的位置
fun main (){
val num1 = 80
val num2 = 100
val result = n1+n2
}
三:noinline 与 crossinline
noinline:一个高阶函数接受了两个或者以上的函数类型,这时我们给函数加上 inline
关键字,Koltin 编译器会自动将所有的Lambda表达式全部进行内联。
只想内联其中一个,就可以使用 noinline 关键字。
例如:
inline fun inlineTest( block1 : () -> Unit, noinline block2 : () -> Unit){
}
为什么要使用 "非内联" 函数 :
1.这是因为 内联 的 函数类型 参数 在编译的时候会进行代码替换。因此它并没有真正
的参数属性。
2.非内联的 函数类型 参数 可以自由的传递给其他任何函数。因为它是一个真正的参数。
3. 内联 函数类型 只允许传递给另一内联函数。
内联函数 与 非内联函数:
内联函数:伪参,函数返回(调用函数)
非内联函数:实参,局部返回(return@方法名)
crossinline: 保证函数一定不使用 return 关键字
例如:会报错
inline fun runRunnable(block : () -> Unit){
val runnable = Runnable{
block()
}
runnable.run
}
内联函数允许使用 return 关键字进行函数返回,由于我们在匿名类中调用的 函数类型 参数,不可能进行外层调用函数的返回,最多只能对匿名类中的函数调用进行返回。(即,在高阶函数中创建了另外的Lambda 或者 匿名类的实现,并且在这些实现中调用 函数类型参数 , 此时再将高阶函数声明为内联函数,就会提示错误)
解决:
inline fun runRunnable(crossinline block : () -> Unit){
val runnable = Runnable{
block()
}
runnable.run
}
原因分析:内联函数允许函数返回 与 匿名类不允许函数返回 冲突
四:高阶函数的应用
1.SharedPreferences
定义:
fun SharedPreferences.open(block : SharedPrefences .Editor .() -> Unit ){
val editor = edit()
editor.block()
editor.apply()
}
使用:
SharedPreferences("data",Context.MODE_PRIVATE).open{
putString("name","Jasmine")
putInt("age",18)
putBoolean("married",false)
}
注:官方有提供kotlin 下 的 SharedPreferences (SharedPreferences.edit)
2.ContentValues
定义:
fun cvOf(vararg pairs : Pair <String, Any?> ) = ContentValues().apply{
for(pair in pairs ){
val key = pair.first
val value = pair.second
when(value){
is Int -> put(key, value)
is Long -> put(key, value)
....
null -> putNull(key)
}
}
}
注:官方有提供kotlin 下 的 ContentValues
val values = contentValueOf("name" to "Jasmine" , "age" to 18, "married" to false)
db.insert("Person",null,values)
五:编写好用的工具方法(顶层方法,扩展函数,高阶函数)
Toast:顶层函数(不定义在任何类中的函数才是顶层函数),扩展函数
定义:
fun String.showToast(context: Context , duration : Int = Toast.LENGTH_SHORT){
Toast.make(context,this,duration).show()
}
使用:
"This is Toast".showToast(this,Toast.LENGTH_LONG)
SnackBar:顶层方法,扩展函数,高阶函数
定义:
fun View.showSnackbar(text : String, actionText : String? = null, duration:Int = Snackbar.LENGTH_SHORT,block : ( () - >Unit ) ? = null){
val snackbar = Snackbar.make(this,text,duration)
if ( actionText != null && block != null ){
snackbar.setAction(actionText){
block()
}
}
snackbar.show()
}
使用:
view.showSnackbar("This is Snackbar","Action"){
}