【问题标题】:Kotlin: Can you use named arguments for varargs?Kotlin:你可以为可变参数使用命名参数吗?
【发布时间】:2016-12-20 19:57:50
【问题描述】:

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

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

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

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

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

是否可以对可变参数使用命名参数?有什么巧妙的变通办法吗?

【问题讨论】:

    标签: function kotlin default-value variadic-functions named-parameters


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      可以通过在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))
      

      【讨论】:

      • 更改签名对函数的用户不好。按照传统, vararg 是最后一个,当你想像你指出的那样正常调用它时,它可能会导致问题; numbers = *intArrayOf(...) 是这里的路。
      【解决方案3】:

      Kotlin Docs 明确表示:

      可变数量的参数 (Varargs)

      函数的参数(通常是最后一个)可以用 vararg修饰符:

      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
      }
      

      允许将可变数量的参数传递给函数:

        val list = asList(1, 2, 3)
      

      在函数内部,vararg 类型的参数 T 可以作为 T 的数组,即上例中的 ts 变量具有类型 Array&lt;out T&gt;.

      只有一个参数可以标记为vararg。如果有vararg 参数 不是列表中的最后一个,以下参数的值 可以使用命名参数语法传递,或者,如果参数 有一个函数类型,通过在括号外传递一个 lambda。

      当我们调用vararg-函数时,我们可以一个接一个地传递参数, 例如asList(1, 2, 3),或者,如果我们已经有一个数组并且想要 将其内容传递给函数,我们使用 spread 运算符 (在数组前面加上*):

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

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

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

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

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        可变参数可以是参数列表中的任何位置。请参阅下面的示例,了解如何使用不同的参数集调用它。顺便说一句,任何调用也可以在右括号后提供 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")
        }
        

        【讨论】:

          猜你喜欢
          • 2013-09-10
          • 2011-03-24
          • 2011-01-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-06-23
          • 1970-01-01
          相关资源
          最近更新 更多