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

Kotlin: Can you use named arguments for varargs?

例如,您的函数可能具有复杂的签名和可变参数:

fun complicated(easy: Boolean = false, hard: Boolean = true, vararg numbers: Int)

你应该能够像这样调用这个函数是有道理的:

complicated(numbers = 1, 2, 3, 4, 5)

遗憾的是编译器不允许这样做。

可变参数可以使用命名参数吗?有什么巧妙的解决方法吗?

可以通过在 vararg:

之后移动可选参数来解决
fun complicated(vararg numbers: Int, easy: Boolean = false, hard: Boolean = true) = {}

那么可以这样调用:

complicated(1, 2, 3, 4, 5)
complicated(1, 2, 3, hard = true)
complicated(1, easy = true)

请注意,尾随的可选参数需要始终与名称一起传递。 这不会编译:

complicated(1, 2, 3, 4, true, true) // compile error

另一种选择是为显式数组参数保留 vararg 糖:

fun complicated(easy: Boolean = false, hard: Boolean = true, numbers: IntArray) = {}

complicated(numbers = intArrayOf(1, 2, 3, 4, 5))

要将命名参数传递给可变参数,请使用 spread operator:

complicated(numbers = *intArrayOf(1, 2, 3, 4, 5))

Kotlin 文档明确指出:

Variable number of arguments (Varargs)

A parameter of a function (normally the last one) may be marked with vararg modifier:

fun <T> asList(vararg ts: T): List<T> {
  val result = ArrayList<T>()
  for (t in ts) // ts is an Array
    result.add(t)
  return result
}

allowing a variable number of arguments to be passed to the function:

  val list = asList(1, 2, 3)

Inside a function a vararg-parameter of type T is visible as an array of T, i.e. the ts variable in the example above has type Array<out T>.

Only one parameter may be marked as vararg. If a vararg parameter is not the last one in the list, values for the following parameters can be passed using the named argument syntax, or, if the parameter has a function type, by passing a lambda outside parentheses.

When we call a vararg-function, we can pass arguments one-by-one, e.g. asList(1, 2, 3), or, if we already have an array and want to pass its contents to the function, we use the spread operator (prefix the array with *):

val a = arrayOf(1, 2, 3)
val list = asList(-1, 0, *a, 4)

From: https://kotlinlang.org/docs/reference/functions.html#variable-number-of-arguments-varargs

要恢复,您可以使用扩展运算符使其看起来像:

complicated(numbers = *intArrayOf(1, 2, 3, 4, 5))

希望对您有所帮助

vararg 参数可以在参数列表中的任何位置。请参阅下面的示例,了解如何使用不同的参数集调用它。顺便说一句,任何调用也可以在右括号后提供 lambda。

fun varargs(
  first: Double = 0.0,
  second: String = "2nd",
  vararg varargs: Int,
  third: String = "3rd",
  lambda: ()->Unit = {}
) {
  ...
}

fun main(args: Array<String>) {
  val list = intArrayOf(1, 2, 3)

  varargs(1.0, "...", *list, third="third")
  varargs(1.0, "...", *list)
  varargs(1.0, varargs= *list, third="third")
  varargs(varargs= *list, third="third")
  varargs(varargs= *list, third="third", second="...")
  varargs(varargs= *list, second="...")

  varargs(1.0, "...", 1, 2, 3, third="third")
  varargs(1.0, "...", 1, 2, 3)
  varargs(1.0)

  varargs(1.0, "...", third="third")
  varargs(1.0, third="third")
  varargs(third="third")
}