函数类型
函数
Kotlin 中的函数使用fun
关键字声明,函数名称的命名规则与变量一致:
fun double(x: Int): Int {
return 2 * x
}
函数作为类型的表示
Kotlin 的函数类型是一种特殊的类型,它可以描述函数的类型信息,包括函数的参数和返回值类型。在 Kotlin 中,函数类型是以 (参数类型) -> 返回值类型
的形式来表示的。
例如,一个函数类型为 (Int, String) -> Boolean
的函数类型表示接收两个参数,一个为 Int 类型,一个为 String 类型,返回一个 Boolean 类型的值。
在 Kotlin 中,函数类型可以用作变量类型、参数类型、返回值类型、以及类型别名等。这使得函数可以像普通变量一样被传递、赋值、以及作为函数的参数和返回值使用。这种特性在函数式编程中非常重要。
同时,Kotlin 还提供了一种特殊的函数类型 () -> Unit
,它表示不接收任何参数,也不返回任何值的函数类型,类似于 Java 中的 void 类型。
函数的参数
函数参数使用 Pascal 表示法定义,即 name: type。参数用逗号隔开。 每个参数必须有显式类型:
有参函数定义:
fun powerOf(number: Int, exponent: Int): Int { /*……*/ }
无参函数定义:
fun powerOf(): Int { /*……*/ }
参数可以添加默认值:
fun read( b: Array<Byte>, off: Int = 0, len: Int = b.size, ) { /*……*/ }
如果从基类中覆盖一个有参的并且填写了默认值的方法,那么子类在覆盖此方法时的定义,必须从签名中省略默认参数值;也就是说,覆盖方法会沿用被覆盖方法的参数默认值:
open class A { open fun foo(i: Int = 10) { /*……*/ } } class B : A() { override fun foo(i: Int) { /*……*/ } // 不能有默认值 }
可变参数
fun <T> asList(vararg ts: T): List<T> { val result = ArrayList<T>() for (t in ts) // ts is an Array result.add(t) return result } asList(1, 2, 3) // 或者使用伸展操作符,将数组展开 val a = arrayOf(1, 2, 3) val list = asList(-1, 0, *a, 4)
函数的返回值
无返回值函数
// 无返回值函数可以使用 Unit 类型来表示,也可以省略返回值类型。 fun printHello() { println("Hello") } fun printWorld(): Unit { println("World") }
单返回值函数
// 单个返回值函数可以使用任意类型来表示,如果没有显式指定返回值类型,则会根据函数体自动推断出返回值类型。 fun add(a: Int, b: Int): Int { return a + b } fun sub(a: Int, b: Int) = a - b
多返回值函数
// Kotlin 中没有直接支持多个返回值的语法,但可以使用 Pair、Triple 等数据类来返回多个值。 fun getPerson(): Pair<String, Int> { return Pair("Alice", 18) } fun getUser(): Triple<String, Int, String> { return Triple("Bob", 20, "male") }
函数的调用
正常通过类型匹配调用
fun foo( bar: Int = 0, baz: Int, ) : Int { println("bar=$bar baz=$baz") return bar + baz } // 正常通过类型匹配进行调用 val r = foo(1, 2)
函数参数中,如果每个参数都有默认值,那么可以省略函数参数,或者省略部分函数参数
fun foo1(x: Int = 1, y: Int = 2) {} foo1() foo2(1) // 传入x=1 foo3(y = 1) // 传入y=1,x使用默认值,这里需要使用具名参数
如果函数中有默认值的参数在无默认参数之后,这时候又不想传入默认值参数,就必须使用具名参数
fun foo2( bar: Int = 0, baz: Int, ) : Int { println("bar=$bar baz=$baz") return bar + baz } foo2(baz = 2)
同样的,如果所有没有默认值的参数都在前面,那么有默认值的参数都可以省略:
fun reformat( str: String, normalizeCase: Boolean = true, upperCaseFirstLetter: Boolean = true, divideByCamelHumps: Boolean = false, wordSeparator: Char = ' ', ) { /*……*/ } reformat('This is a long String!')
函数的调用,在没有具名参数的情况下,优先使用函数类型匹配函数。
局部函数
Kotlin 支持局部函数,即一个函数在另一个函数内部,局部函数可以访问外部函数(即闭包)的局部变量:
fun dfs(graph: Graph) {
val visited = HashSet<Vertex>()
fun dfs(current: Vertex) {
if (!visited.add(current)) return
for (v in current.neighbors)
dfs(v)
}
dfs(graph.vertices[0])
}
匿名函数
val sum = fun(x: Int, y: Int): Int {
return x + y
}
val s = sum(1, 2)
println(s)
// list的map方法,就可以传入一个匿名函数
val list = listOf(1, 2, 3, 4, 5)
val newList = list.map(fun(i): Int { return i * 2 })
闭包
fun returnFun(): () -> Int {
var count = 0
return { count++ }
}
fun main() {
val function = returnFun()
val function2 = returnFun()
println(function()) // 0
println(function()) // 1
println(function()) // 2
println(function2()) // 0
println(function2()) // 1
println(function2()) // 2
}
returnFun返回了一个函数,这个函数没有入参,返回值是Int。可以用变量接收它,还可以调用它。function和function2分别是创建的两个函数实例。 可以看到,每调用一次function(),count都会加一,说明count 被function持有了而且可以被修改。而function2和function的count是独立的,不是共享的。
最后更新于
这有帮助吗?