一、高阶函数及lambda表达式
1.1、闭包
- 闭包指的是函数的运行环境
- 闭包可以持有函数的运行环境
- 函数内部可以定义函数
- 函数内部也可以定义类
fun main(args: Array<String>) {
// text()
val ss = text2()
ss()//10
ss.invoke()//11
ss.invoke()//12
}
//函数不保存状态 闭包可以让函数携带状态
fun text() {
var a = 10
println(a)
a++
}
//闭包 lambda表达式 函数式编程 函数可以作为方法的返回值 方法可以作为函数的参数
fun text2(): () -> Unit {
var a = 10
return {
println(a)
a++
}
}
1.2、高阶函数
Kotlin中,以函数作为参数或者返回值的函数称为高阶函数。函数可以自由传递、赋值、在合适的时候调用,Lambda,并且赋值给一个变量,所有符合参数和返回值的任意Lambda以及函数都可以作为高阶函数的参数。
fun main(args: Array<String>) {
//方法的引用
val s = ::add
println(cacl(1, 2, s))//3
//方法的引用
val s1 = ::sub
println(cacl(1, 2, s1))//-1
}
//求两个数的和 工具
fun add(a: Int, b: Int): Int {
return a + b
}
//求两个数的差 工具
fun sub(a: Int, b: Int): Int {
return a - b
}
//第三个参数是函数类型 说明kotlin里面的函数可以传递函数参数 如果函数里面传递函数参数的话 就称为高阶函数
fun cacl(a: Int, b: Int, block: (Int, Int) -> Int): Int {
val result = block(a, b)
// val result = block.invoke(a, b)
return result
}
1.3、lambda表达式
Lambda 表达式是一个匿名函数
fun main(args: Array<String>) {
//函数的参数定义出来之后 可以自动推断出类型 返回值不需要写 推断出当前的返回值类型
//匿名函数 lambda表达式
val s = cacl2(100, 212, { m: Int, n: Int ->
m + n
})
println(s)//312
val s1 = cacl2(100, 212, { m: Int, n: Int ->
m - n
})
println(s1)//-112
}
//第三个参数是函数类型 说明kotlin里面的函数可以传递函数参数 如果函数里面传递函数参数的话 就称为高阶函数
fun cacl2(a: Int, b: Int, block: (Int, Int) -> Int): Int {
val result = block(a, b)
// val result = block.invoke(a, b)
return result
}
1.4、lambda表达式去()
调用的时候如果最后一个参数是lambada表达式时 可以把()前移,当lambda是函数唯一的实参时,可以去掉函数调用的括号。
fun main(args: Array<String>) {
//调用的时候最后一个参数传递的是匿名函数lambda表达式
//如果最后一个参数是lambada表达式时 可以把()前移
val s = cacl3(100, 212) { m, n->
m + n
}
println(s)//312
//调用的时候最后一个参数传递的是匿名函数lambda表达式
//如果最后一个参数是lambada表达式时 可以把()前移
val s1 = cacl3(100, 212) { m, n->
m - n
}
println(s1)//-112
}
//第三个参数是函数类型 说明kotlin里面的函数可以传递函数参数 如果函数里面传递函数参数的话 就称为高阶函数
fun cacl3(a: Int, b: Int, block: (Int, Int) -> Int): Int {
val result = block(a, b)
// val result = block.invoke(a, b)
return result
}
1.5、lambda表达式单独纯在
fun main(args: Array<String>) {
//嵌套匿名函数
//()调用方式
// {
// println("hello Word")
// }()
//.invoke()调用
{
println("hello Word")
}.invoke()
//嵌套有名函数
// fun sayHello(){
// println("hello Word")
// }
// sayHello()
}
1.6、有参的lambda表达式
//嵌套有参的lambda表达式 实现a+b的和
val invoke = { a: Int, b: Int ->
a + b
}.invoke(1, 2)
println(invoke)//3
1.7、保存lambda表达式
//接收有参lambda表达式
val s= {a:Int,b:Int->
a+b
}
//调用方式一:()调用,不可以空调用
val value = s(1,2)
println(value)//3
//调用方式二:.invoke 可以空调用(?.invoke)
val value2 = s.invoke(1,2)
println(value2)//3
1.8、lambda表达式使用it
it
并不是Kotlin
中的一个关键字(保留字)。it
是在当一个高阶函数中Lambda
表达式的参数只有一个的时候可以使用it
来使用此参数,省略参数列表和->
。it
可表示为单个参数的隐式名称,,是Kotlin
语言约定的。
fun main(args: Array<String>) {
//lambda表达式使用的时候如果只有一个参数可以省略参数名,默认是通过it来实现的
val s = padd(100) {
it + 100
}
println(s)//200
}
//高阶函数
fun padd(m: Int, block: (a: Int) -> Int): Int {
return block(m)
}
1.9、lambda表达式返回值
Lambda表达式返回不用return 返回值是最后一行的返回值
//s 是lambda表达式返回值
val s= {
100+1
"11"
}.invoke()
println(s)//11
1.10、”_“作为参数
在使用Lambda表达式的时候,可以用下划线(_
)表示未使用的参数,表示不处理这个参数。
val maps = mapOf<String, String>("1" to "A", "2" to "B", "3" to "C")
//正常打印
maps.forEach { key, value ->
println("$key ==== $value")
}
//不需要key的时候
maps.forEach { _, value ->
println(value)
}
1.11、常见的lambda表达式
val list = arrayListOf("1", "100", "2121")
/*--------------------------------------foreach------------------------------------*/
// foreach是一个扩展函数,foreach参数是一个函数类型
// public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit
list.forEach(::println)
//打印结果:
// 1
// 100
// 2121
list.forEach({char->
println(char)
})
//lambda表达式在最后一位 可以括号前移 迁移之后()没有参数 可以省略
list.forEach{char->
println(char)
}
//lambda只有一个参数 只有一个参数可以使用it
list.forEach {
println(it)
}
/*--------------------------------------indexOfFirst------------------------------------*/
//indexOfFirst是一个扩展函数,indexOfFirst参数是一个函数类型, 函数的返回值是boolean类型, indexOfFirst返回值是Int
//public inline fun <T> List<T>.indexOfFirst(predicate: (T) -> Boolean): Int
val s1=list.indexOfFirst {
it.startsWith("1")
}
println(s1)//0
二、集合
2.1、List集合
使用listOf
函数来构建一个不可变的List(只读的List)
使用mutableListOf
、arrayListOf
、ArrayList
创建可变集合
/*----------------------------listof----------------------------------*/
val list = listOf<String>("A", "张三", "L")
//list[0]="2"//listOf创建 不可修改
//list.add//listOf创建 不可添加
for (s in list) {
println(s)
}
/*----------------------------mutableListOf---------------------------*/
val list2 = mutableListOf<String>("A", "张三", "L")
list2[0] = "B"//mutableListOf创建 可以修改
//list2.set(1,"李四")
list2.add("S")//添加元素
for ((index,s) in list2.withIndex()) {
println("index=$index,s=$s")
}
/*-------------------------------java的集合------------------------------*/
val list3 = arrayListOf<String>("A")
list3.add("zh")//可添加
list3.add("us")
list3.add("us1")
list3[2]="A"//可修改
list3.forEach {
println(it)
}
val list4=ArrayList<String>()
list4.add("zh")//可添加
list4.add("cc")
list4[0]="us"//可修改
list4.forEachIndexed { index, s ->
println("index=$index,s=$s")
}
List集合的遍历
List集合可通过componentX()
获取集合中的第几个元素,超出集合大小会报错。可以通过for
、forEach
循环遍历。
val list = ArrayList<String>()
list.add("A")
list.add("张三")
list.add("李四")
list.add("王五")
//通过componentX()获取集合中的第几个元素,超出集合大小会报错
println(list.component2())//张三
/*------------------------for循环遍历--------------------*/
//不带角标
for (s in list) {
println(s)//A
}
//带角标
for ((index, s) in list.withIndex()) {
println("index=$index ,s=$s")//index=0 ,s=A
}
/*----------------------forEach循环遍历------------------*/
//不带角标
list.forEach {
println(it)//A
}
//带角标
list.forEachIndexed { index, s ->
println("index=$index ,s=$s")//index=0 ,s=A
}
2.2、Set集合
Set集合 不能存放重复的元素,setOf
创建不可变集合(只可读)
使用mutableSetOf
、hashSetOf
、HashSet
创建可变集合
// set集合 不能存放重复的元素
// set集合没有位置概念 不可对一个位置元素修改
/*---------------------setOf--------------------*/
val set1 = setOf<Int>(100, 201, 302, 403)
// set1[1]=222 //不可修改
// set1.add //不可添加
for (i in set1) {
println(i)
}
/*--------------------mutableSetOf--------------------*/
val mutableSetOf = mutableSetOf<Int>(103, 206, 309, 412)
mutableSetOf.add(111)//可添加
for ((index, s) in mutableSetOf.withIndex()) {
println("index=$index ,s=$s")
}
/*--------------------java集合--------------------*/
val hashSetOf = hashSetOf<String>("AA", "BB", "CC")
hashSetOf.add("DD")//可添加
hashSetOf.forEach {
println(it)
}
val hashSet = HashSet<String>()
hashSet.add("AAAA")//可添加
hashSet.add("BBBB")
hashSet.add("CCCC")
hashSet.forEachIndexed { index, s ->
println("index=$index ,s=$s")
}
Set集合遍历
Set集合可使用for
、forEach
遍历集合。
val hashSet = HashSet<String>()
hashSet.add("张三")
hashSet.add("李四")
hashSet.add("王五")
/*------------------------for循环遍历--------------------*/
//不带角标
for (s in hashSet) {
println(s)//李四
}
//带角标
for ((index, s) in hashSet.withIndex()) {
println("index=$index ,s=$s")//index=0 ,s=李四
}
/*----------------------forEach循环遍历------------------*/
//不带角标
hashSet.forEach {
println(it)//李四
}
//带角标
hashSet.forEachIndexed { index, s ->
println("index=$index ,s=$s")//index=0 ,s=李四
}
2.3、Map集合
使用mapOf
创建不可变Map集合(只可读)
使用mutableMapOf
、hashMapOf
、HashMap
创建可变Map集合
- emptyMap():创建一个空map
- hashMapOf():创建一个hashMap
- linkedMapOf():创建一个linkedMap
- sortedMapOf():创建一个sortedMap
/*-------------------------mapOf-------------------------------*/
val map1 = mapOf<String, String>("A" to "11", "B" to "22", Pair("C", "33"))
for (key in map1.keys) {
println(map1[key])//11
}
/*-------------------------mutableMapOf-------------------------------*/
val map2 = mutableMapOf<String, String>("A" to "11", "B" to "22", Pair("C", "33"))
map2["E"] = "222"//可添加
map2.put("D", "1")//可添加
for (key in map2.keys) {
println(map2[key])//11
}
/*-------------------------java 集合-------------------------------*/
val map3 = hashMapOf<Int, Int>(1 to 0, 2 to 0)
for (key in map3.keys) {
println(map3[key])//0
}
val map4 = HashMap<String, String>()
map4["A"]="1"
map4["B"]="2"
map4["C"]="3"
for (key in map4.keys) {
println(map4[key])//1
}
Map集合遍历
使用forEach
变量Map集合
可通过getOrDefault
获取值,并设置默认值
val hashMap = HashMap<String, Int>()
hashMap["A"] = 1
hashMap["B"] = 1
hashMap["C"] = 1
//通过key获取value
println(hashMap["E"])//null
print(hashMap.getOrDefault("D","不存在值"))//不存在值
/*---------------------------- 遍历所有的key ----------------------------*/
hashMap.keys.forEach {
println(it)//A
}
/*---------------------------- 遍历所有的values ----------------------------*/
hashMap.values.forEach {
println(it)//1
}
/*---------------------------- 遍历所有的 key 和values ----------------------------*/
hashMap.forEach { ket, it ->
println("ket=$ket it=$it")//ket=A it=1
}
2.4、集合过滤
find{...}
:查找第一个满足条件的元素。
filter{...}
: 查找出满足条件的所有元素集合。
filterTo(集合){...}
:把满足条件的元素添加到新的集合中。
filterIndexed{...}
:和filter{}
函数作用类似,只是可以操作集合中元素的下标(index
)。
drop(num)
: 过滤集合中前num
个元素。
dropWhile{...}
: 相同条件下,和执行takeWhile{...}
函数后得到的结果相反。
dropLast(num)
: 过滤集合中后num
个元素。
dropLastWhile{...}
: 相同条件下,和执行takeLastWhile{...}
函数后得到的结果相反。
filterNot{...}
: 和filter{}
函数的作用相反。
filterNotNull()
: 过滤掉集合中为null
的元素。
slice
: 返回指定区间的集合中的元素。
take(num)
: 返回集合中前num
个元素组成的集合。
takeWhile{...}
: 循环遍历集合,从第一个元素开始遍历集合,当第一个出现不满足条件元素的时候,退出遍历。然后把满足条件所有元素组成的集合返回。
takeLast(num)
: 返回集合中后num
个元素组成的集合。
takeLastWhile{...}
: 循环遍历集合,从最后一个元素开始遍历集合,当第一个出现不满足条件元素的时候,退出遍历。然后把满足条件所有元素组成的集合返回。
val list = listOf("张三", "李四", "王五", "赵六", "张四", "李五", "李六")
val list2 = listOf("周芷若", "张无忌", "张五", "李善长", "林青霞", "李寻欢")
//找到第一个姓张的
val a = list.find {
it.startsWith("张")
}
println(a)//张三
//把第一个集合中所有姓张的找出来
val b = list.filter {
it.startsWith("张")
}
println(b)//[张三, 张四]
// 把两个集合中所有姓张的找到并存放在同一个集合中
val mutableListOf = mutableListOf<String>()
list.filterTo(mutableListOf) {
it.startsWith("张")
}
list2.filterTo(mutableListOf) {
it.startsWith("张")
}
println(mutableListOf)//[张三, 张四, 张无忌, 张五]
// 把第一个集合中角标为偶数的元素找出来
val c = list.filterIndexed { index, s ->
index % 2 == 0
}
println(c)//[张三, 王五, 张四, 李六]
val listOf = listOf<String>("1", "ni", "2", "wo", "3", "ta")
//drop:返回包含去掉前n个元素(这里是4)的所有元素的列表
println(listOf.drop(4))//[3, ta]
//dropLast:返回包含去掉后n个元素(这里是4)的所有元素的列表
println(listOf.dropLast(4))//[1, ni]
//dropLastWhile:返回根据特定的函数 从最后一项开始 直到不满足条件后返回 列表
println(listOf.dropLastWhile {
it == "ta"
})//[1, ni, 2, wo, 3]
//dropWhile:根据特定的函数 从第一项开始 直到不满足条件后返回 列表
println(listOf.dropWhile {
it == "1"
})//[ni, 2, wo, 3, ta]
//filter:返回满足条件之外的的所有元素的集合
println(listOf.filterNot{
it=="2"
})//[1, ni, wo, 3, ta]
//filterNotNull:返回集合中不为null的数据集合
println(listOf.filterNotNull())//[1, ni, 2, wo, 3, ta]
//slice:返回指定区间的集合中的元素
println(listOf.slice(1..3))//[ni, 2, wo]
//take:返回集合的前n项(这里是3)
println(listOf.take(3))//[1, ni, 2]
//takeLast:返回集合的后n项(这里是3)
println(listOf.takeLast(3))//[wo, 3, ta]
//takeWhile:从第一项开始判断,直到不符合就返回,返回符合的前几项数据
println(listOf.takeWhile {
it=="1"||it=="ni"
})//[1, ni]
//takeWhile:从第最后一项开始判断,直到不符合就返回,返回符合的后几项数据
println(listOf.takeLastWhile {
it=="3"||it=="ta"
})//[3, ta]
2.5、集合排序
sortBy
:集合正序排列 。
sortByDescending
:集合降序排序。
sortWith{...}
:方法中,传入的 compareBy({属性1},{属性2},…)
参数, compareBy()
这里的参数个数是可变的,但是都是默认的升序排列。
fun main(args: Array<String>) {
val list = listOf("z", "b", "d")
//正序排序
println(list.sorted())//[b, d, z]
//倒序排序
println(list.sortedDescending())//[z, d, b]
val list2 = listOf<Person>(Person("张三", 18), Person("李四", 23), Person("王五", 11))
//根据年龄正序排序
val a = list2.sortedBy {
it.age
}
println(a)//[Person(name=王五, age=11), Person(name=张三, age=18), Person(name=李四, age=23)]
//根据年龄倒序排序
val b = list2.sortedByDescending {
it.age
}
println(b)// [Person(name=李四, age=23), Person(name=张三, age=18), Person(name=王五, age=11)]
val list3 = listOf<Person>(Person("张三", 23), Person("张三丰", 23), Person("王五", 24))
//先根据年龄排序,如果一样再根据名字长度排序
println(list3.sortedWith(compareBy({ it.age }, { it.name.length })))//[Person(name=张三, age=23), Person(name=张三丰, age=23), Person(name=王五, age=24)]
}
data class Person(var name: String, var age: Int)
2.6、集合分组
groupBy{...}
: 即根据条件把集合拆分为为一个Map<K,List<T>>
类型的集合。
val list = listOf("张三", "李四", "王五", "赵六", "张四", "李五", "李六")
//姓张的一组 姓李的一组 其他一组
val a = list.groupBy {
val substring = it.substring(0, 1)
when (substring) {
"张" -> "张"
"李" -> "李"
else -> "其他"
}
}
println(a)//{张=[张三, 张四], 李=[李四, 李五, 李六], 其他=[王五, 赵六]}
2.7、集合最值
max()
: 获取集合中最大的元素,若为空元素集合,则返回null
。
maxBy{...}
: 获取方法处理后返回结果最大值对应那个元素的初始值,如果没有则返回null
。
min()
: 获取集合中最小的元素,若为空元素集合,则返回null
。
minBy{...}
: 获取方法处理后返回结果最小值对应那个元素的初始值,如果没有则返回null
。
val list = listOf(100, 21, 112)
//最大值
println(list.max())//112
//最小值
println(list.min())//21
val list2 = listOf<Person>(Person("张三", 18), Person("李四", 23), Person("王五", 11))
//对象最大值
val a=list2.maxBy {
it.age
}
println(a)//Person(name=李四, age=23)
//对象最小值
val b=list2.minBy {
it.age
}
println(b)//Person(name=王五, age=11)
2.8、集合去重复
distinct()
: 去除重复元素。
distinctBy{...}
: 根据操作元素后的结果去除重复元素。
val list = listOf("张三", "李四", "王五", "赵六", "张四", "李五", "张三", "李六")
//toSet 把重复的姓名去除
val toSet = list.toSet()
println(toSet)//[张三, 李四, 王五, 赵六, 张四, 李五, 李六]
//distinct 把重复的姓名去除
val distinct = list.distinct()
println(distinct)//[张三, 李四, 王五, 赵六, 张四, 李五, 李六]
// distinctBy 把重复的同姓的去掉
val a=list.distinctBy {
it.substring(0, 1)
}
println(a)//[张三, 李四, 王五, 赵六]
2.9、集合拆封
partition
: 判断元素是否满足条件把集合拆分为有两个Pair
组成的新集合。
val list = listOf("张三","李四","王五","赵六","张四","李五","张三","李六")
// 姓张的一部分,另外的一部分
val a=list.partition {
it.startsWith("张")
}
println(a.first)//[张三, 张四, 张三]
println(a.second)//[李四, 王五, 赵六, 李五, 李六]
2.10、集合重新组合
map{...}
: 把每个元素按照特定的方法进行转换,组成一个新的集合。
val list2 = listOf<Person>(Person("张三", 18), Person("李四", 23), Person("王五", 11))
//将Person里面每一个name获取出来
val a = list2.map {
it.name
}
println(a)//[张三, 李四, 王五]
//将Person里面每一个姓氏获取出来
val b = list2.map {
it.name.subSequence(0, 1)
}
println(b)//[张, 李, 王]
2.11、集合相加
sumBy{...}
: 根据元素运算操作后的结果,然后根据这个结果计算出累加的值。
sumByDouble{...}
: 和sumBy{}
相似,不过sumBy{}
是操作Int
类型数据,而sumByDouble{}
操作的是Double
类型数据。
val list = listOf<Person>(Person("张三", 18), Person("李四", 23), Person("王五", 11))
//求出所有人的年龄之和
val ages = list.sumBy {
it.age
}
println(ages)//52
//如果是Double 可以使用sumByDouble
// val ages2 =list.sumByDouble {
// it.age
// }
2.12、集合之间的运算
intersect
(交集),subtract
(差集),union
(并集),minus
(补集)。
val list1= listOf<String>("1","1","2","3")
val list2= listOf<String>("3","2","0")
println(list1.intersect(list2))//[2, 3] ---->交集(返回的是Set集合)
println(list1.subtract(list2))//[1] -------->差集(返回的是Set集合)
println(list1.union(list2))//[1, 2, 3, 0] -->并集(返回的是Set集合)
println(list1.minus(list2))//[1, 1] -------->补集(返回的非Set集合)
三、四大函数(apply、let、with、run)
3.1、四大函数使用
apply
:用某对象的apply
函数,在函数范围内,可以任意调用该对象的任意方法,并返回该对象。
let
:默认当前这个对象作为闭包的it参数,返回值是函数里面最后一行,或者指定return
返回值。
with
:是一个单独的函数,并不是Kotlin
中的extension,返回值是函数里面最后一行,可以直接调用对象的方法,是let
和apply
的结合,调用方式与其他三个函数不同。
run
:和apply函数很像,只不过run
函数是使用最后一行为返回值,apply
返回当前自己的对象。
fun main(args: Array<String>) {
val list = arrayListOf<String>("张三", "李四")
/*---------------------------- apply ----------------------------*/
/**
* <T> T.apply(block: T.() -> Unit): T
* 任意类型都有apply函数 T.() -> Unit 带接收者的函数字面值
* lambda表达式里this代表调用的对象
* 在lambda表达式里可以访问对象的方法
* apply函数返回值就是调用者本身
*/
list?.apply {
add("赵五")
add("王六")
}
println(list)//[张三, 李四, 赵五, 王六]
/*---------------------------- let ----------------------------*/
/**
* <T, R> T.let(block: (T) -> R): R
* 任意类型都有let函数
* let函数参数是函数参数,函数参数的参数是调用者本身
* let函数返回值是函数参数的返回值,就是lambda表达式的返回值
*/
list?.let {
it.add("123")
it.add("456")
""
}
println(list)//[张三, 李四, 赵五, 王六, 123, 456]
/*---------------------------- with ----------------------------*/
/**
* <T, R> with(receiver: T, block: T.() -> R): R
* with函数是一个独立函数,在任意地方均可调用
* with函数接收两个参数
* 第一个参数接收任意类型
* 第二个参数是函数参数,并且这个函数参数是带接收者的函数字面值,接受者是第一个参数
* with函数返回值是第二个函数参数的返回值
* 相当于apply和let的结合
*
*/
with(list) {
this.add("11")
add("12")
11
}
println(list)//[张三, 李四, 赵五, 王六, 123, 456, 11, 12]
/*---------------------------- run ----------------------------*/
/**
* <T, R> T.run(block: T.() -> R): R
* 任意类型都有run扩展函数
* run函数参数是带接收者的函数 接收者就是调用者本身
* run函数返回值就是函数参数的返回值
*/
list?.run {
add("456")
add("111")
1
}
println(list)//[张三, 李四, 赵五, 王六, 123, 456, 11, 12, 456, 111]
}
// set {
// name
// sayHello()
// }
/**
* T.()->Unit
* lambda相当于定义在T里面的函数 访问对象里面的字段或者方法
* 调用的时候两种:1.Data().block() 2.block(Data())
*/
fun set(block: Data.() -> Unit) {
//调用方式一
Data().block()
//调用方式二
// block(Data())
}
class Data {
var name: String = "张三"
fun sayHello() {
}
}
3.2、四大函数比较
函数名 | 函数定义结构 | 接收参数 | 函数体中对象 | 返回值 | 备注 |
---|---|---|---|---|---|
apply | T.apply(block: T.() -> Unit): T | 接收的是带接收者函数,接收者就是调用者本身 | this指代当前对象或者省略 | 返回值就是调用者本身 | 任意类型都有apply函数 T.() -> Unit 带接收者的函数字面值 |
let | <T, R> T.let(block: (T) -> R): R | 接收的是函数参数,函数参数的参数是调用者本身 | it指代当前对象 | 返回值是函数参数的返回值,就是lambda表达式的返回值 | 任意类型都有let函数 |
with | <T, R> with(receiver: T, block: T.() -> R): R | 第一个参数接收任意类型,第二个参数是函数参数,并且这个函数参数是带接收者的函数字面值,接受者是第一个参数 | this指代当前对象或者省略 | 返回值是第二个函数参数的返回值 | with函数是一个独立函数,在任意地方均可调用 |
run | <T, R> T.run(block: T.() -> R): R | 接收的是带接收者的函数,接收者就是调用者本身 | this指代当前对象或者省略 | 返回值就是函数参数的返回值 | 任意类型都有run扩展函数 |