函数 基础写法Kotlin语言中文站
在Kotlin中使用关键字fun声明一个函数:
fun printInfo() {
println("This is a function.")
}
如果携带参数呢?如下main函数所示:
fun main(args: Array) { println("length:${args.size}") }
如果一个函数没有返回值,如上两个函数,那么它的返回值类型默认是Unit,可省略不写:
我们看看Unit的源码:
package kotlin
public object Unit {
override fun toString() = "kotlin.Unit"
}
看注释是说对应Java中的void,那就没必要纠结了。
如果有返回值呢,那就在函数后面写明返回值类型:
fun getRandomNumber(range : Int) : Int {
return Random.nextInt(range)
}
fun getBean(t: T) : T {
return t
}
如果函数的函数体可以由单个表达式(表达式表示有返回值)计算出来,也可以简写成如下形式:
//单个表达式可以计算出来
fun sum(a: Int, b: Int) : Int{
return a + b
}
//可以简写成如下形式, 它和上面的写法是等价的,不过更加简单明了
fun sum(a: Int, b: Int) : Int = a + b
//单个表达式可以计算出来
fun max(a:Int, b:Int) : Int {
if(a > b) {
return a
}
return b
}
//max
fun largeNumber(a:Int, b:Int) : Int = if(a > b) a else b
默认参数
Kotlin中函数可以有默认值,当省略相应的参数时就会使用默认值;相对Java而言,它可以减少一大堆重载函数。我们来看一个案例:
Android中EventBus库大家应该都不陌生,在很多业务场景下能实现代码逻辑解耦。如下是EventBus的一个消息事件类。
public final class IMessageEvent {
public String msg_what;
public String arg1;
public String arg2;
public int arg3;
public int arg4;
public BeBOMessageEvent(String msg_what) {
this.msg_what = msg_what;
}
public BeBOMessageEvent(String msg_what, int arg3) {
this.msg_what = msg_what;
this.arg3 = arg3;
}
public BeBOMessageEvent(String msg_what, String arg1) {
this.msg_what = msg_what;
this.arg1 = arg1;
}
public BeBOMessageEvent(String msg_what, String arg1, int arg3) {
this.msg_what = msg_what;
this.arg1 = arg1;
this.arg3 = arg3;
}
public BeBOMessageEvent(String msg_what, String arg1, String arg2, int arg3) {
this.msg_what = msg_what;
this.arg1 = arg1;
this.arg2 = arg2;
this.arg3 = arg3;
}
}
可以发现重载的构造函数比较多。 如果用Kotlin来写,将会快捷很多:
class IMessageEvent(var msg_what: String, var arg1: String = "", var arg2: String = "", var arg3: Int = 0, var arg4: Int = 0) {
companion object {
val ENABLE_DEBUG_MODE = "ENABLE_DEBUG_MODE"
}
}
使用如下:
//1个参数,其他全部用默认值 val messageEvent = IMessageEvent(IMessageEvent.ENABLE_DEBUG_MODE) //2个参数,其他用默认值 val messageEvent1 = IMessageEvent(IMessageEvent.ENABLE_DEBUG_MODE, "A0001") //或者这样(只传递首尾参数) val messageEvent2 = IMessageEvent(IMessageEvent.ENABLE_DEBUG_MODE, "A0001", "", 0, 50)
默认参数在某些场景下(一个默认参数在一个无默认值的参数之前),使用上会产生歧义,导致编译报错:
fun printInfo(tag: String = "hepingdev##", info: String) {
println("$tag$info")
}
调用如上函数:
看错误提示是因为没有传递参数值info,所以这就为难了(我是想第一个参数使用默认值,只传递第二个参数)。
在kotlin中使用具名参数解决这类问题:
fun main(args: Array) { printInfo(info = "函数") }
也就是指明给哪个参数赋值,如上指明给info参数赋值。
可变数量的参数(vararg)
当方法的参数数据类型已经确定,但是参数的个数不确定,就可以使用可变数量的参数。 如下代码所示:
funmutableListOf(vararg elements: T): List { val result = ArrayList () for (t in elements) // elements is an Array result.add(t) return result }
我们调用上面mutableListOf函数时,常见场景如:
- 一个一个的传递参数
fun main(args: Array) { //一个一个的传递参数 var list = mutableListOf ("1", "2", "3") }
- 将一个数组的内容传递给该函数,使用展开操作符(在数组前面加*)
//传递一个数组的内容
var aList = arrayOf("1","2","3")
var concatList = mutableListOf("23234", *aList, "w3r")
println(concatList) //打印:[23234, 1, 2, 3, w3r]
它类似JavaScript里面的展开操作符(…),只是写法不一样。
同样,如果vararg参数不是列表中最后一个参数,就需要使用具名参数传递其后的参数值。如下:
fun中缀函数subList(vararg elements: T, endIndex: Int): List ? { if(elements.isEmpty() || endIndex == 0) return null val result = ArrayList () for (e in elements) { result.add(e) if(result.size - 1 >= endIndex) { break } } return result } //调用 fun main(args: Array ) { var aList = listOf ("1","2","3") //具名参数endIndex subList(aList, endIndex = 1) }
如下代码中until即中缀函数,调用中缀函数不需要调用的点和圆括号。
for (i in 1 until 5){
println("$i") //1,2,3,4
}
声明一个中缀函数必须满足以下要求:
- 必须是成员函数(对象的方法)或扩展函数。
- 必须只有一个参数,且参数不得是可变数量的参数,同时不能有默认值。
- 必须采用infix关键字修饰。
按照上面的要求,我们简单声明两个中缀函数看看,如下:
class InfixFunction {
infix fun printInfo(onlyParams : String) {
println(onlyParams)
}
}
fun main(args: Array) {
val mInfixFunction = InfixFunction()
mInfixFunction printInfo "打印这个值" //打印这个值
}
infix fun Int.add_(b : Int) : Int = this + b
fun main(args: Array) {
val a = 1
val c = a add_ 2
println(c) //3
}
很“高大尚”的一种语法糖,是不是很有意思呢。
上一篇:Kotlin学习历程——对象声明与伴生对象



