为了账号安全,请及时绑定邮箱和手机立即绑定

【备战春招】第11天 Kotlin方法进阶

标签:
Kotlin

课程名称:移动端架构师


课程章节: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,期待后面的继续学习



https://img1.sycdn.imooc.com/63eb364900012a5115070862.jpg


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
移动开发工程师
手记
粉丝
0
获赞与收藏
4

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消