开始
高阶函数是将函数作为参数和返回值的函数,函数可以作为对象进行传递,函数对象的类型由参数和返回值表示,参数名可省略
1 | (Int, Int) -> Int |
函数类型支持可空类型,支持嵌套,支持类型别名
1 | ((Int, Int) -> Unit)? // 可空类型 |
函数类型实例化
通过以下方式可以实例化一个函数类型,lambda 表达式和匿名函数是函数字面量,通过 invoke 方法或使用调用操作符 method()
调用函数对象
- lambda 表达式
- 匿名函数
- 使用具名函数引用
- 顶层函数、局部函数、扩展函数:
::method
- 成员方法:
String::toInt
- 主构造器:
::ClassName
- 顶层函数、局部函数、扩展函数:
匿名函数
可以指定返回类型,返回类型推断与具名函数相同
1 | val f: (Int, Int) -> Int = fun (a: Int, b: Int): Int { |
lambda 表达式
1 | val f: (Int, Int) -> Int = { |
简写语法
- 当 lambda 表达式是函数的最后一个方法时,lambda 表达式传参可以放在括号外面
- 当函数只有 lambda 表达式一个参数时,函数的括号可以省略
- 当 lambda 表达式只有一个参数时,可以省略参数声明,使用隐式参数 it
- 若 lambda 表达式中的参数未使用,在参数声明处使用
_
替代
SAM
函数式接口 SAM:当接口中只有一个抽象方法时,接口称为函数式接口,函数式接口可以进行 SAM 转换
1 | interface Handler { |
函数字面量的接收者
一个函数类型中可以带有接收者,表示指定接收者中的一个函数类型
1 | class Person { |
通过 lambda 和匿名函数两种字面量获取接收者函数
1 | // 在字面量内部,隐式传入了接收者引用this |
限定 this 表达式
this 默认指向最内层的作用域对象 (类、扩展函数、带有接收者的函数字面量),可以使用限定 this 表达式获取外部作用域的 this,格式为 this@label
,由于类声明无法设置标签,因此通常使用隐式标签
当调用 this 的属性和方法时,可以省略 this,但存在同名顶层函数或顶层属性时,最好指定 this
1 | class A { |
内联函数
当一个函数接收一个 lambda 表达式作为参数,lambda 表达式在调用时会产生一个函数对象,且会捕获闭包,当 lambda 表达式过多时性能开销较大,此时可以使用内联提升性能
在需要传入 lambda 参数的函数上用 inline 关键字修饰,此时该函数称为内联函数
直接 return
java 的 lambda 表达式中支持 return,本质是一个方法的返回
kotlin 的 lambda 表达式中不支持直接使用 return,需要使用标签才能返回
使用内联后,内联函数会将 lambda 表达式中的代码直接插入到调用处,减少了 lambda 表达式对象的创建,当 lambda 表达式中包含 return 时,return 也会被内联到内联函数中,因此 return 是从内联函数中返回
1 | fun main() { |
noinline 关键字
使用 noinline 关键字指定某个 lambda 表达式不进行内联,通常当传入的函数字面量作为函数对象使用时,不进行内联
1 | inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) { |
操作符重载
使用 operator 关键字实现指定名称的成员函数或扩展函数,Kotlin 只支持有限的几种操作符重载
1 | class OrdersList: IndexedContainer { |
一元操作
表达式 | 翻译为 |
---|---|
+a |
a.unaryPlus() |
-a |
a.unaryMinus() |
!a |
a.not() |
a++ |
a.inc() |
a-- |
a.dec() |
二元操作
表达式 | 翻译为 |
---|---|
a + b |
a.plus(b) |
a - b |
a.minus(b) |
a * b |
a.times(b) |
a / b |
a.div(b) |
a % b |
a.rem(b) |
a..b |
a.rangeTo(b) |
a..<b |
a.rangeUntil(b) |
a in b |
b.contains(a) |
a !in b |
!b.contains(a) |
a == b |
a?.equals(b) ?: (b === null) |
a != b |
!(a?.equals(b) ?: (b === null)) |
a > b |
a.compareTo(b) > 0 |
a < b |
a.compareTo(b) < 0 |
a >= b |
a.compareTo(b) >= 0 |
a <= b |
a.compareTo(b) <= 0 |
a += b |
a.plusAssign(b) |
a -= b |
a.minusAssign(b) |
a *= b |
a.timesAssign(b) |
a /= b |
a.divAssign(b) |
a %= b |
a.remAssign(b) |
其他操作符
索引访问操作符 | 翻译为 |
---|---|
a[i] |
a.get(i) |
a[i, j] |
a.get(i, j) |
a[i_1, ……, i_n] |
a.get(i_1, ……, i_n) |
a[i] = b |
a.set(i, b) |
a[i, j] = b |
a.set(i, j, b) |
a[i_1, ……, i_n] = b |
a.set(i_1, ……, i_n, b) |
invoke 操作符 | 翻译为 |
---|---|
a() |
a.invoke() |
a(i) |
a.invoke(i) |
a(i, j) |
a.invoke(i, j) |
a(i_1, ……, i_n) |
a.invoke(i_1, ……, i_n) |