高阶函数
函数式语言一个典型的特征就在于函数是头等公民,我们不仅可以像类⼀样在顶层直接定义⼀个函数,也可以在一个函数内部定义一个局部函数,如下所示:
fun foo(x: Int) {
fun double(y: Int): Int {
return y * 2
}
println(double(x))
}
所谓的高阶函数,你可以把它理解成“ 以其他函数作为参数或返回值的函数” 。
函数类型
在Kotlin中,函数类型的格式非常简单,举个例子:
(Int) -> Unit
从中我们发现,Kotlin中的函数类型声明需遵循以下几点:
-
通过 -> 符号来组织参数类型和返回值类型,左边是参数类型,右边 是返回值类型;
-
必须用一个括号来包裹参数类型;
-
返回值类型即使是 Unit,也 必须显式声明。
如果是一个没有参数的函数类型,参数类型部分就用()来表示。
() -> Unit
如果是多个参数的情况,那么我们就需要用逗号来进行分隔,如:
(Int, String) -> Unit
此外,Kotlin还支持为声明参数指定名字,如下所示:
(errCode: Int, errMsg: String) -> Unit
支持可空类型:
(errCode: Int, errMsg: String?) -> Unit
如果该函数类型的变量也是可选的话,我们还可以把整个函数类型变成可选:
((errCode: Int, errMsg: String?) -> Unit)?
函数类型作为一个函数的返回值(高阶函数):
(Int) -> ((Int)-> Unit))
这表示传入一个类型为 Int 的参数,然后返回另一个类型为(Int) -> Unit 的函数。
方法和成员引用
Kotlin存在⼀种特殊的语法,通过
两个冒号来实现对于某个类的方法进行引用。
例如,假如我们有⼀个 CountryTest 类的对象实例
countryTest,如果要引用它的
isBigEuropeanCountry 方法,就可以这么写:
countryTest::isBigEuropeanCountry
此外,我们还可以直接通过这种语法,来定义⼀个类的构造方法引用变量。
class Book(val name: String)
fun main() {
val getBook = ::Book
println(getBook("Dive into Kotlin").name)
}
其中 getBook 的类型为(name: String)-> Book,类似的可以引用类中的某个成员变量,如:
Book::name
这对于在对Book类对象的集合应用⼀些函数式API的时候,会显得格外有用,比如:
fun main() {
val bookNames = listOf(
Book("Thinking in Java"),
Book("Dive into Kotlin")
).map(Book::name)
println(bookNames)
}