全网最全面的由浅到深的Kotlin基础教程(七)

前言

本篇文章接着上一篇文章全网最全面的由浅到深的Kotlin基础教程(六)继续进阶学习kotlin,建议看完上一篇文章,再来看本篇文章。本篇主要分析一些常用的kotlin函数源码,以及用kotlin简单实现Rxjava的几个操作符。坚持将kotlin系列的前6篇看完的,那么恭喜你再将这最后一篇看完,你就成为一名合格的kotlin开发者了。

1. kotlin标准函数源码解析

1.1 apply

源码及分析注释如下:

/*
public 访问修饰符
inline fun 内联函数
<T> 泛型定义
T.apply 泛型T的扩展函数
(block: T.() -> Unit) 输入参数为一个名为block的lambda表达式,
		其中T.() 是一个泛型扩展函数,这种写法使得lambda表达式持有T的this对象,
		当做固定写法来理解即可。
: T apply函数的返回类型仍然为T
*/
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
   
   
    //契约函数,暂时不用关注,可以不写的
    contract {
   
   
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    //执行lambda表达式的逻辑
    block()
    //最终仍然返回T对象本身
    return this
}

1.2 also

与apply函数的意义一样,只是also函数的lambda表达式持有it,而apply函数的的lambda表达式持有this,源码及分析注释如下:

/*
public 访问修饰符
inline fun 内联函数
<T> 泛型定义
T.also 为泛型T定义扩展函数also
block: (T) -> Unit also函数中传入的参数是lambda表达式,该lambda表达式有一个T泛型的参数,返回值为空
: T also函数的最终返回值仍然为T泛型
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
   
   
    contract {
   
   
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    //执行lambda表达式,将T泛型的this对象传入block函数,因此block通过it持有T泛型的this对象
    block(this)
    //不管你上面的lambda表达式干了啥,最终仍然返回T泛型对象本身
    return this
}

1.3 run

源码及分析注释如下:

/*
public 访问修饰符
inline fun 内联函数
<T, R> 定义两个泛型
T.run 为T泛型定义扩展函数run
block: T.() -> R run函数有一个参数是lambda表达式,该lambda表达式通过T泛型扩展函数,拥有T泛型的this对象,返回类型为R
: R run函数的返回类型是R泛型
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
   
   
    contract {
   
   
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    //执行lambda表达式
    //因为lambda表达式拥有T泛型的this对象
    //因为lambda表达式返回的是R,因此返回值由lambda表达式的最后一行决定
    //return this.block()  //this可以省略
    return block()
}

1.4 let

与run函数的意义一样,只是let函数的lambda表达式持有it,而run函数的的lambda表达式持有this,源码及分析注释如下:

/*
public 访问修饰符
inline fun 内联函数
<T, R> 定义两个泛型
T.let 为T泛型定义扩展函数let
block: (T) -> R lambda表达式参数,输入T泛型(lambda表达式如果只有一个参数,则参数名默认为it),输出为R泛型
: R 最终返回的类型是R泛型
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
   
   
    contract {
   
   
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    //执行lambda表达式
    //因为lambda表达式传入的是this,因此lambda表达式通过it持有T泛型的对象
    //因为lambda表达式输入的T,返回的是R,因此返回值由lambda表达式的最后一行决定
    return block(this)
}

1.5 with

与run函数的意义一样,只是调用方式不一样而已,run是泛型扩展函数,而with是普通的函数,源码及分析注释如下:

/*
public 访问修饰符
inline fun 内联函数
<T, R> 定义两个泛型
with(receiver: T, block: T.() -> R) 这是一个普通的函数,并非扩展函数,包括两个参数,第一个T泛型的参数,第二个是lambda表达式,lambda表达式通过T泛型扩展函数,拥有T泛型的this对象,返回类型为R
: R 最终返回类型是R
*/
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
   
   
    contract {
   
   
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    //block的最后一行是返回值
    return receiver.block()
}

1.6 takeIf

源码及分析注释如下:

/*
public 访问修饰符
inline fun 内联函数
<T> 泛型定义
T.takeIf 为泛型T定义扩展函数takeIf
predicate: (T) -> Boolean takeIf函数中传入的参数是lambda表达式,该lambda表达式有一个T泛型的参数,返回值为Boolean
: T? takeIf函数最终返回的可空的T泛型类型
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mekeater

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值