当传递给可变参数参数时,Kotlin 可以过滤掉空参数吗?

问题描述

kotlin 中的此函数需要零对或多对属性

fun trackEvent(vararg properties: Pair<Any?,Any?>){
   ...
}

通常是这样调用的,效果很好

trackEvent( 
            "time" to timeStr,"user" to user
          )

其中 timeStruser 是可空字符串

到目前为止一切顺利,但这需要我们手动将所有变量单独传递给跟踪函数,而只传递一个对象会更容易。为了解决这个问题,我创建了一个函数,它接收一个 Kotlin 类并输出一个 Pair 对象数组

fun Any.toArrOfPairs(): Array<Pair<Any?,Any?>>
{
  ...
}

并希望像这样使用它

trackEvent(
            *source?.toArrOfPairs()
          )

一个编译器错误;然而:

compiler error

似乎 kotlin 担心 source 为空的情况。在这种情况下,是否可以优雅地告诉它使用空数组调用 trackEvent

同样,如果我们组合方法调用 trackEvent 如下,有没有办法告诉 kotlin “如果 source 为空,只需传入其他参数(在这种情况下 - “时间" 对)

trackEvent(
               "time" to timeStr,*source?.toArrOfPairs()
              )

解决方法

让你的辅助函数接受一个可为空的接收器并为空情况返回一个空数组:

fun Any?.toArrOfPairs(): Array<Pair<Any?,Any?>>
{
  this ?: return emptyArray()
  // Your original code ...
}

然后在使用时跳过空安全调用,因为不再需要:

trackEvent(*source.toArrOfPairs())

我不确定我是否完全理解你问题的最后一部分。如果你想结合显式参数和数组,你可以:

trackEvent(
    "time" to timeStr,*source.toArrOfPairs()
)

如果你只想在源为空的情况下使用显式参数,你可以使用 Elvis 运算符,但它有点难看,因为你必须将显式参数放在数组中:

trackEvent(
    *(source?.toArrOfPairs() ?: arrayOf("time" to timeStr))
)

或者只是使用 if 语句。也许更冗长,但更容易阅读:

if (source != null) {
    trackEvent(*source.toArrOfPairs())
} else {
    trackEvent(
        "time" to timeStr
    )
}