布景

一般在项目开发中,我们经常会在要害节点上埋点,而且埋点中会增加一些额定参数,这些参数通常是成对呈现参数个数是不固定的。如下:

//界说事件EVENT_ID
const val EVENT_ID = "event_xmkp"
//留意:这儿传入的是vararg可变参数
fun String.log(vararg args: String) {
    if (args.size % 2 > 0) {
        throw RuntimeException("传入的参数有必要是偶数")
    }
    if (args.isEmpty()) {
        buryPoint(this)
    } else {
        //留意这儿:可变参数在作为数组传递时需求运用扩展(spread)操作符(在数组前面加 *)
        buryPoint(this, *args)
    }
 }
private fun buryPoint(eventId: String, vararg args: String) {
    if (args.isNotEmpty()) {
        Log.e(TAG, "buryPoint: $eventId, args: ${args.toList()}")
    } else {
        Log.e(TAG, "buryPoint: $eventId")
    }
}

调用方式如下:

EVENT_ID.log()
EVENT_ID.log("name", "小马快跑")
EVENT_ID.log("name", "小马快跑", "city", "北京")

示例中可变参数可所以0个、2个、4个,执行结果:

2022-11-22 19:00:54 E/TTT: eventID: event_xmkp
2022-11-22 19:00:54 E/TTT: eventID: event_xmkp, args: [name, 小马快跑]
2022-11-22 19:00:54 E/TTT: eventID: event_xmkp, args: [name, 小马快跑, city, 北京]

能够看到经过界说可变参数,在调用方能够灵活地传入0个多个参数,下面就剖析下Kotlin办法中的可变参数。

留意:可变参数在作为数组传递时需求运用扩展操作符(在数组前面加 *),假如去掉 *号,编译器会报如下错:

Kotlin | 使用vararg可变参数

Kotlin中运用可变参数

Java中可变参数规矩:

  • 运用…表明可变参数
  • 可变参数只能在参数列表的最后
  • 可变参数在办法体中最终是以数组的形式拜访

Kotlin中可变参数规矩:

  • 不同于Java,在Kotlin中假如 vararg 可变参数不是列表中的最后一个参数, 能够运用签字参数语法传递其后的参数的值。
  • Java相同,在函数内,能够以数组的形式运用这个可变参数的形参变量,而假如需求传递可变参数,需求在前面加上扩展(spread)操作符(在数组前面加 *),第一节已给出示例。

对Kotlin可变参数反编译

对上一节中的String.log()代码反编译成Java代码:

//kt代码
fun String.log(vararg args: String) {
    if (args.size % 2 > 0) {
        throw RuntimeException("传入的参数有必要是偶数")
    }
    if (args.isEmpty()) {
        buryPoint(this)
    } else {
        //留意这儿:可变参数在作为数组传递时需求运用扩展(spread)操作符(在数组前面加 *)
        buryPoint(this, *args)
    }
 }

转换之后:

 // Java代码
 public final void log(@NotNull String $this$log, @NotNull String... args) {
      ...
      if (args.length % 2 > 0) {
         throw (Throwable)(new RuntimeException("传入的参数有必要是偶数"));
      } else {
         if (args.length == 0) {
            this.buryPoint($this$log);
         } else {
            this.buryPoint($this$log, (String[])Arrays.copyOf(args, args.length));
         }
      }
 }
  • Kotlinvararg args: String参数转换成Java的 @NotNull String... args
  • Kotlinspread扩展操作符*args转换成Java(String[])Arrays.copyOf(args, args.length),可见最终还是经过体系复制生成了数组。

材料

【1】https://www.kotlincn.net/docs/reference/functions.html