kotlin使用vararg可变参数(代码片段)

-小马快跑- -小马快跑-     2023-04-03     775

关键词:

文章目录

背景

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

//定义事件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中使用可变参数

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

关于可变参数varargs(代码片段)

  今天在看源码的时候,面对以下有点蒙蔽,在这里对可变参数做一下总结。  主要理解取自一个博客,c版本的:https://www.cnblogs.com/bettercoder/p/3488299.html示例输出如下:  更多详细解释请看: http://www.cplusplus.com/referenc... 查看详情

kotlin函数(代码片段)

...数fun<T>singletonList(item:T):List<T>//...尾部递归函数Kotlin支持一种称为尾部l递归的函数式编程。这使得一 查看详情

Kotlin Native iOS 字符串格式化与可变参数

】KotlinNativeiOS字符串格式化与可变参数【英文标题】:KotlinNativeiOSstringformattingwithvararg【发布时间】:2021-02-0605:37:16【问题描述】:基于thisissue关于使用NSString格式化我尝试在使用vararg时实现格式化的多平台实现,到目前为止没... 查看详情

kotlin的变长参数(代码片段)

...;顾名思义变长参数就是某个参数可以接受多个值;在Kotlin里面位置可以随意放,而在java里面只能做最后一个。下面我们来一段代码展示一下效果:funmain(args:Array<String>) hell(1,2,3,4,5,6,string="Hello")hello(3.0,1,2... 查看详情

kotlin的变长参数(代码片段)

...;顾名思义变长参数就是某个参数可以接受多个值;在Kotlin里面位置可以随意放,而在java里面只能做最后一个。下面我们来一段代码展示一下效果:funmain(args:Array<String>) hell(1,2,3,4,5,6,string="Hello")hello(3.0,1,2... 查看详情

java可变参数varargs

...单的方式,来传递个数可变的实参。本文介绍这一机制的使用方法,以及这一机制与数组、泛型、重载之间的相互作用时的若干问题。 到J2SE1.4为止,一直无法在Java程序里定义实参个数可变的方法—&mdas 查看详情

kotlin中类函数(代码片段)

在kotlin中函数可以在类外部定义也可以在类内部定义,前者即为全局函数,后者,是类成员函数,语法一样packageloaderman.democlassPersonfundemo(name:String="name",age:Int)println(name+age)packageloadermanimportloaderman.demo.Personfunmain(arg:Array<String>)... 查看详情

kotlin泛型总结★(泛型类|泛型参数|泛型函数|多泛型参数|泛型类型约束|可变参数结合泛型|out协变|in逆变|reified检查泛型参数类型)(代码片段)

文章目录一、泛型类二、泛型参数三、泛型函数四、多泛型参数五、泛型类型约束六、可变参数vararg关键字与泛型结合使用七、使用[]运算符获取指定可变参数对象八、泛型out协变九、泛型in逆变十、泛型invariant不变十一、泛型... 查看详情

Chez Scheme 中的 FFI,用于具有可变参数 (varargs) 的 C 函数

...(varargs)【发布时间】:2019-11-1611:01:12【问题描述】:我想使用foreign-procedure在ChezScheme中为C的printf函数编写FFI。但我不知道我应该把什么作为签名,因为printf函数中的最后一个参数是 查看详情

Kotlin:你可以为可变参数使用命名参数吗?

】Kotlin:你可以为可变参数使用命名参数吗?【英文标题】:Kotlin:Canyouusenamedargumentsforvarargs?【发布时间】:2016-12-2019:57:50【问题描述】:例如,您的函数可能具有复杂的签名和可变参数:funcomplicated(easy:Boolean=false,hard:Boolean=true,... 查看详情

《android》chap.2入门kotlin(代码片段)

HelloKotlinkotlin每一行代码的结尾不需要加分号。编程之本变量关键词语法规则代码原词用法valvalue声明一个不可变的变量,在初始赋值后不能在被重新赋值varvariable声明一个可变的变量,在初始赋值后仍能在被重新赋值代... 查看详情

kotlin集合操作⑤(map集合|获取map值|map遍历|可变map集合)(代码片段)

文章目录一、Map集合二、获取Map值三、Map遍历四、可变Map集合一、Map集合调用mapOf函数创建Map集合,键值对元素有两种初始化方式:使用to函数进行初始化:在参数中使用键to值的方式进行初始化;使用Pair对象进行初始化:传入Pair(键,值... 查看详情

java可变参数列表

...知时,称其为可变参数列表。在以前的Java代码中,可以使用Object数组来实现这样的功能。因为,所有的类都是直接或间接继承于Object类。 VarArgs.javapackagesample; classA1{} publicclassVarArgs{    &n 查看详情

java可变参数基本使用(代码片段)

文章目录Java可变参数可变参数简介可变参数的基本使用Java可变参数可变参数简介可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了,方法的参数类型已经确定,个数不确定,我们可以... 查看详情

kotlin学习笔记——接口抽象类泛型扩展集合操作符与java互操作性单例(代码片段)

注:编码工具为IntelliJ目录接口示例定义变量示例变量默认值抽象类示例实现接口泛型泛型类泛型函数泛型实现自定义map变换泛型类联合泛型函数实现泛型函数实现类型约束泛型vararg参数vararg示例泛型vararg类型判断out和in关键... 查看详情

kotlin与java的异同(代码片段)

本文章只为了方便查阅。文章目录Kotlin简介Kotlin与Java的异同1.函数2.变量变量类型可变变量不可变变量3.类和属性有参数的构造方法setter和getter4.枚举和"when"枚举when5."while"和"for"循环"while"循环"for"循... 查看详情

在kotlin序列化中使用datastore(代码片段)

...本都会在后台使用Protos对数据进行序列化。您也可以使用Kotlin序列化,结合使用DataStore与自定义数据类。这有助于减少样板代码,且无需学习或依赖于Protobuf库,同时仍可以为数据提供架构。您需要完成以下几项操作:... 查看详情

kotlin集合操作②(mutablelist可变列表集合|修改mutablelist集合的mutator函数)(代码片段)

文章目录一、MutableList可变列表集合二、修改MutableList集合的mutator函数1、添加元素运算符+=和删除元素运算符-=2、通过Lambda表达式筛选要删除的元素一、MutableList可变列表集合使用listOf函数创建的List集合是只读列表集合;... 查看详情