Kotlin的语言很简洁,或许可以通过lambda表达式就能惊叹它很优秀,不过函数或许也是它更出彩的地方。

在开始前,我们需要认识到很多类,如集合类,Kotlin其实是基于Java的api,只是对Java类的API又做了拓展,丰富了其API,而不是推倒重建,在JVM重做一套,所以Kotlin是很大一部分API是基于Java对应的API实现的。但是可能会有疑惑为什么Kotlin的集合类有那么丰富的API呢?

可以用下面的例子来验证下:在Kotlin中,计算数组的最大值其简单,代码如下:

1
2
3
4
5
6
val persons = listOf(
Person("cyning", 21),
Person("gaodaren", 18),
Person("damei", 4))

println(persons.maxBy(Person::age))

若是去打印person的类型,会发现实际上它是java的类型

1
println(persons.maxBy(Person::age))

打印:
class java.util.Arrays$ArrayList.
这正验证了刚才咱们说的:Kotlin在很多实细节上是基于java实现的。

带默认值的函数

在开始前需要了解下函数的默认参数值,在其他语言如python, 不是什么新鲜玩意儿。

所谓带参数值的函数,实际上在调用函数时,选择性指定参数,否则函数验证按照参数个数,类型,顺序查找到对应签名的函数。

如:

1
2
3
4
fun update(name:String, age:Int = 0, address:String = "") {

//todo do somethings
}

实际上我们不为函数传值age和address,他可以走默认值0和””,也可以指定的传一个值。

1
2
update("cyning", 18)
update("cyning", address = "china")

这样一个函数可以提供多个参数的同时,确保了某些参数使用默认值。

为了保证java能调起来Kotlin的带默认值的参数,我们需要在Kotlin中用@JvmOverloads来确保多个同名函数的重载

顶层的函数

顶层参数主要是为了解决类似utils工具类的问题,函数可以在类的顶层(不在类的内部),调用时,类似调用java的静态工具类。

对于java调用kotlin的顶层函数,需要注意导入的类是这个函数所在的类名加Kt后缀。

拓展函数

在Kotlin中,我们是可以为其他类添加函数,好像是这个函数本身有的方法一样。这样的函数我们称之为拓展函数。定义规则如下:

这样String就多个一个方法lastChar()函数。

1
2
3
fun  String.lastChar():Char = this.get(length-1)

"cyning li".lastChar()

其中=后面的可以理解成是在String类的操作(其中的this自己体会下)

若嫌不够,再来一个例子:

1
2
3
4
5
6
7
8
9
10
11
fun  List<Int>.maxElem():Int  {
var max:Int = this.get(0);
this.forEach { //this实际上就是接收者对象
max = (if (it > max) it else max )
}
return max;
}

// 调用
val list = listOf<Int>(20, 4, 67, 90);
println(list.maxElem())

其中的forEach的this实际上是指List的一个对象。

在其他Kotlin使用,只需要导入相关的包名,类名,拓展方法名,就可以正常使用了,类似于调用顶层函数。

所有拓展方法调用的方法都必须是接收类型的共有方法。