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

Can Kotlin filter out null arguments when passed to a varargs parameter?

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

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

通常这样调用,效果很好

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

其中 timeStruser 是可为空的字符串

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

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

并希望像这样使用它

trackEvent(
            *source?.toArrOfPairs()
          )

存在编译错误;然而:

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

类似地,如果我们组合方法并如下调用 trackEvent,是否有办法告诉 kotlin“如果 source 为 null,只需传入其他参数(在本例中 - “时间”对)

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

让你的辅助函数接受一个可为 null 的接收器和 return 一个用于 null 情况的空数组:

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
    )
}