携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
前言
本文来巩固Kotlin 函数声明,及默认参数的知识点。
本文大纲
1. 回顾 Java 的函数重载
在 Java 中,当要实现同一种功能,但函数入参,出参不一样的函数的时候,可以用到函数重载功能。
确实是好特性,但当重载函数过多时,代码就显得臃肿,如下是一个显示 Toast 的工具类,在经过功能不断扩展后,成了一个拥有多个重载方法的类:
// ...
public static void show(CharSequence msg) {
show(Toast.LENGTH_SHORT, msg, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
}
public static void show(Activity activity, int resId) {
show(activity, resId, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
}
public static void show(Activity activity, CharSequence msg) {
show(Toast.LENGTH_SHORT, activity, msg, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
}
/**
* 当msg0不为空时展示msg0,忽略msg1;否则显示msg1
*/
public static void show(Activity activity, CharSequence msg0, CharSequence msg1) {
if (!TextUtils.isEmpty(msg0)) {
show(Toast.LENGTH_SHORT, activity, msg0, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
} else if (!TextUtils.isEmpty(msg1)) {
show(Toast.LENGTH_SHORT, activity, msg1, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
}
}
// ...
有点类似于 get/set 方法一样,这是典型臃肿,信息量底的代码。怎样才能更精简的表达同样的功能,不同的入参的特性呢?有的,就是默认参数。
2. 重载函数的替代者,默认参数
Kotlin 拥有默认参数的特性,用 Kotlin 实现上述 Java 代码,可以简化为:
fun show(msg: CharSequence,
msg2: CharSequence? = null,
context: Context = Global.getApplicationContext(),
gravity: Int = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM,
duration: Int = Toast.LENGTH_SHORT) {
// 具体实现
}
可以看到,声明默认参数的方法很简洁,只需要把可以使用默认参数的入参用“=“号赋一个默认值即可。一般来说,建议把必须提供的参数写在前面,有默认参数的入参排在后面。因为在调用时,函数的入参默认是按顺序映射的,按上面的顺序排列的话,只需要填完必须的参数即可;而如果还想提供可选参数,就继续按顺序填。
那如果只想提供部分可选参数,比如上面的show函数我只想提供duration参数,跳过其他可选参数呢?Kotlin 提供了如下调用办法:
show("this is a toast");
show("this is a toast, duration = Toast.LENGTH_LONG);
show(msg = "this is a toast, duration = Toast.LENGTH_LONG);
show(duration = Toast.LENGTH_LONG, msg = "this is a toast);
可以发现,Kotlin 方法调用时,可以显式的指明对象和入参的映射关系,无需按顺序传递。注意,这个特性不分必须参数和可选参数,所有的参数都可以用这种形式指定映射。
平时在写代码时,可能已经发现,Android Studio 对没有提供名字的函数参数,已经默认显示这个参数对应的名字。
Flutter 的 Dart 语言也有默认参数特性,而且 Flutter 组件对默认参数的使用可谓是淋漓尽致。它会把一个控件所有可配置的参数都提供在构造函数中,而且把必须参数和可选参数分开。这样开发者可以很方便的看到它必须配置和可以配置的所有参数,不用再去慢慢找这个控件提供了什么设置方法。
3. 默认参数和函数重载对比
默认参数和重载函数对比,重载函数可以改变入参和出参(返回值),默认参数只可以改变入参。
其次,每一个重载函数都是一个方法,会记录在方法表,占用 Dex 的最大方法数。默认参数会生成 2 个方法,一个是全参数的方法 A,另一个方法 B 也是全参数,但比全参数方法多出来了 flag 参数,该 flag 参数用来记录哪些参数是可选参数。Kotlin 通过这种方式,减少了重载函数可能带来过多的方法数
Kotlin 也支持函数重载。
在掘金(juejin.cn) 一起分享知识,Keep Learning!