函数
Kotlin如何定义一个函数?Kotlin的函数相比Java有哪些新的特性?
1、函数定义
Kotlin中一个函数的定义由一下几个部分组成:
fun 函数名(参数名: 参数类型): 返回类型 {}
①fun:函数定义使用关键字
②参数:传入函数的参数,需要同时指定参数名和参数类型
③返回值:定义返回值类型,如果返回为空可以不写或者使用Unit(相对于Java中的void)
Unit.kt定义:
/**
* The type with only one value: the `Unit` object. This type corresponds to the `void` type in Java.
*/
public object Unit {
override fun toString() = "kotlin.Unit"
}例:
①无返回值
fun name(str: String): Unit {
}
//或者简写
fun name(str: String) {
}②无参且无返回值
fun name(){
}③返回String类型,必须指定返回类型
fun name(str: String): String {
return str
}④表达式作为函数体,返回类型自动推断
fun name(str: String) = str2、参数命名
函数可读性是个大问题,开发中经常遇到传入很多参数的方法,但是参数含义不清楚,需要查看定义处的代码或者AndroidStudio等IDE会显示参数名。比如定义一个函数如下:
fun max(first: Int, second: Int): Int {
return if (first > second) first else second
}使用Kotlin更方便,可以在调用处显示的指明参数名称,这样一眼就能看出参数的含义:

注意参数名必须和函数定义中的参数名一样,否则报错:

指明了函数的名称时,后面所有的参数都得指明对应的参数名称

3、默认参数
Java中函数没有默认参数是一个小遗憾,C++中都有默认参数的语法糖。好在Kotlin中定义函数可以指定默认参数:一来避免了函数的重载,二也减少了调用者的工作量。
例:
//定义第二个参数的默认值为2,调用时可以省略
fun max(first: Int, second: Int = 2): Int {
return if (first > second) first else second
}调用时可以省略第二个默认参数

如果函数有多个参数,前面的参数设定了默认值,后面的参数可以不设置默认值,不会报错,让我们来看看怎么回事?
//定义第一个参数的默认值为2,第二个没有默认值必须显示传入参数
fun max(first: Int = 2, second: Int): Int {
return if (first > second) first else second
}只传入一个参数会报错,因为按顺序这是第一个参数的值,而第二个参数没有默认值。

可以使用前面的参数命名,来显示的指定参数传给第二个参数
![]()
当然参数都传入是不会有问题的:
max(2, 3)4、函数重载
同名函数的参数个数或者参数类型不同即可实现函数的重载。一个函数的签名只看参数列表(参数的个数、参数的类型、参数的顺序)。
例:
fun name(str: String): Unit {
}
fun name(str: String, age: Int) {
}5、扩展函数
详见扩展第一节。
6、局部函数
Kotlin在函数中定义另一个函数,提取抽象的方法,减少代码重复。既可以简化代码量,也无需额外的语法开销。局部函数可以访问外部函数的所有参数和变量。
fun packageData(data: Array<String>) {
//方法中定义一个局部函数
fun checkData() {
if (data.isEmpty()) {
throw Exception()
}
}
//调用局部函数
checkData()
listOf(data)
}上一小节说到的扩展函数也可以定义为局部函数:
fun packageData(data: Array<String>) {
//定义Array<String>类的扩展函数,且为局部函数
fun Array<String>.checkData() {
if (data.isEmpty()) {
throw Exception("empty data")
}
}
//调用扩展函数
data.checkData()
listOf(data)
}7、变长参数函数
Java中参数使用 ... 标志一个参数可以传入0或多个:
public void process(String... args) {
//
}kotlin语言中当然也有这样的语法,使用关键字vararg标志参数是可变长度。
fun process(vararg args: String) {
}如果传递的一组数据以及包装好了,那么在Java中可以直接传递该集合。但是在Kotlin中需要显示的解包数组。使用 * 展开运算符。
fun packageData(data: Array<String>) {
listOf("head", *data)
}8、Lambda函数
Lambda是C++和Java等语言支持的新型函数表达式,原地调用函数。一般形式如下:
var lambda函数名:(参数类型) -> 返回值类型 = {参数名称 -> 函数体}
例:
var lambdaFun: (Int, Int) -> Int = { a, b -> a + b }
