课程名称:移动端架构师
课程章节:Android必备Kotlin核心技术
课程讲师:CrazyCodeBoy LovelyChubby
课程内容:
目录
[高阶方法(函数)
闭包
方法的解构声明
匿名方法
Kotlin方法字面值
高阶方法(函数)
高阶函数是将函数用作参数或返回值的函数。Kotlin支持高阶函数,这样是Kotlin函数式编程的一大特性。
Kotlin源码中使用了大量的高阶函数,下面经常用到的apply 高阶函数的源码,它的主要作用是调用某对象的apply函数,在函数范围内,可以任意调用该对象的任意方法,并返回该对象。
public inline fun <T> T.apply(block: T.() -> Unit): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } block() return this }
apply是一个T泛型的扩展函数,因为它接受一个函数类型的 block参数,所以它也是高阶函数。
函数作为参数
需求:实现一个能够对集合元素进行求和的高阶函数,并且每遍历一个集合元素要有回调
fun List<Int>.sum(callback: (Int) -> Unit): Int { var result = 0 for (v in this) { result += v callback(v) } return result; }
这是一个求List元素和的扩展函数(后面课程会重点接受),它因为接受一个函数类型的callback参数而被成为高阶函数。
val list = listOf(1, 2, 3, 4, 5) val result = list.sum { println(it) } println("计算结果:${result}")
函数作为返回值
需求:实现一个能够对集合元素进行求和的高阶函数,并且返回一个 声明为(scale: Int) -> Float的函数
fun List<String>.toIntSum(): (scale: Int) -> Float { println("第一层函数") return fun(scale): Float { var result = 0f for (v in this) { result += v.toInt() * scale } return result } }
这是一个求List元素和的扩展,它返回一个(scale: Int) -> Float 函数而被成为高阶函数
val listString = listOf("1", "2", "3") val result2 = listString.toIntSum()(2) println("计算结果:${result2}")
闭包(Closure)
方法与闭包的特性可以算是 Kotlin 语言最大的特性了。
其实在 Kotlin 中与其说一等公民是方法,不如说一等公民是闭包。
闭包(Closure)是词法闭包(Lexical Closure)的简称,闭包可以理解为能够读取其他方法内部变量的方法。
例如在JavaScript中,只有方法内部的子方法才能读取局部变量,所以闭包可以理解成“定义在一个方法内部的方法“。在本质上,闭包是将方法内部和方法外部连接起来的桥梁。
闭包的特性:
方法可以作为另一个方法的返回值或参数,还可以作为一个变量的值。
方法可以嵌套定义,即在一个方法内部可以定义另一个方法。
闭包的好处:
加强模块化:闭包有益于模块化编程,它能以简单的方式开发较小的模块,从而提高开发速度和程序的可复用性
抽象:闭包是数据和行为的组合,这使得闭包具有较好抽象能力
灵活:闭包的应用是的编程更加的灵活
简化代码:闭包还能简化代码
需求:实现一个接受一个
testClosure
方法,该方法要接受一个Int类型的v1参数,同时能够返回一个声明为(v2: Int, (Int) -> Unit)
的函数,并且这个函数能够计算v1与v2的和
fun testClosure(v1: Int): (Int, (Int) -> Unit) -> Unit { return fun(v2: Int, printer: (Int) -> Unit) { printer(v1 + v2) } } testClosure(1)(2) { println(it) }
testClosure接收一个Int类型的参数,返回一个带有如下参数的方法
(Int, (Int) -> Unit)
,该方法第一个参数是Int类型,第二个参数是一个接收Int类型参数的方法。testClosure也是高阶方法
解构声明
有时把一个对象 解构 成很多变量会很方便,例如:
var result = Result("success", 0) val (msg, code) = result println("msg:${msg}") println("code:${code}")
这种语法称为解构声明。一个解构声明同时创建多个变量。
解构方法的返回值:
fun testDeco() { var result = result() val (msg, code) = result println("msg:${msg}") println("code:${code}") } fun result(): Result { return Result("good", 1) }
匿名方法
顾名思义,没有方法名的方法:
fun(x: Int, y: Int): Int = x + y
匿名方法看起来非常像一个常规方法声明,除了其名称省略了。其方法体可以是表达式或代码块:
fun(x: Int, y: Int): Int { return x + y }
上文中,我们在闭包的实例中返回的方法就是一个匿名方法。
Kotlin方法字面值
方法字面值(量),可以理解为未声明的方法,即一段方法文本,说白了就是一段代码,可以当作参数来传递。
方法字面量是匿名的,它们在默认情况下没有名称,但是你可以通过将它们绑定到一个变量来给它们一个名字,在 Kotlin 中,Lambda 表达式、匿名方法,都是一种 方法字面值。
//定义了一个变量 tmp,而该变量的类型就是 (Int) -> Boolean var tmp: ((Int) -> Boolean)? = null fun literal() { // { num -> (num > 10) }即是一个方法字面值 tmp = { num -> (num > 10) } }
lambda 表达式可以用作带接收者的方法字面值。
KotlinTest.kt
package com.demo.kotlin fun main() { testSum() testToIntSum() testClosure(1)(2) { //闭包 println(it) } testDecode() //结构声明 literal() //方法字面值 } fun testSum() { val list = listOf(1, 2, 3, 4) val result = list.sum { println(it) } println("计算结果:${result}") } /** * 高阶函数--函数作为参数 * 需求:实现一个能够对集合元素进行求和的高阶函数,并且每遍历一个集合元素要有回调 */ fun List<Int>.sum(callback: (Int) -> Unit): Int { var result = 0 for (v in this) { result += v callback(v) } return result } /** * 高阶函数--函数作为返回值 * 需求:实现一个能够对集合元素进行求和的高阶函数,并且返回一个 声明为(scale: Int) -> Float的函数 */ fun List<String>.toIntSum():(scale: Int) -> Float { println("第一层函数") return fun(scale): Float { var result = 0f; for (v in this) { result += v.toInt() * scale } return result } } fun testToIntSum() { val listStr = listOf("1", "2", "3") val result = listStr.toIntSum()(2) println("toIntSum计算结果:${result}") } /** * 闭包(Closure) * 调用: * testClosure(1)(2) { //闭包 * println(it) * } */ fun testClosure(v1: Int): (v2:Int, (Int) -> Unit) -> Unit { return fun(v2, printer: (Int) -> Unit) { printer(v1 + v2) } } /** * 结构声明 */ fun testDecode() { var result = Result("success", 0) val (msg, code) = result println("msg:${msg} code:${code}") } data class Result(var msg: String, var code: Int) /** * 匿名函数 */ val fun1 = fun(x: Int, y: Int): Int = x + y val fun2 = fun(x: Int, y: Int): Int { return x + y } /** * Kotlin方法字面值 */ fun literal() { //定义一个变量 tmp, 而该变量的类型就是 (Int) -> Boolean var temp: ((Int) -> Boolean?)? = null //{ num -> (num > 10) } 方法字面值 temp = { num -> (num > 10) } println("temp(11):${temp(11)}") }
课程收获:
谢谢老师,老师讲解细致,通俗易懂,逐步深入学习kotlin,期待后面的继续学习