函数的变参

32 阅读2分钟

在 Scala 中,变参(Variable Arguments)  允许函数接收数量不确定的参数,这些参数会被自动封装成一个数组(Array)供函数内部使用。这一特性非常适合处理参数数量不固定的场景(例如求和、打印多个值等)。

基本语法

定义变参时,在参数类型后添加 * 表示该参数是变长的:

def 函数名(参数名: 类型*): 返回类型 = {
  // 函数体内,参数名会被当作 Array[类型] 处理
}

关键特性

  1. 变参的位置变参必须放在参数列表的最后,避免与其他参数的匹配产生歧义:

    // 正确:变参放在最后
    def printInfo(prefix: String, values: String*): Unit = {
      println(s"$prefix: ${values.mkString(", ")}")
    }
    
    printInfo("日志", "a", "b", "c")  // 输出:日志: a, b, c
    
    // 错误:变参不能放在非变参之前
    def invalid(values: Int*, prefix: String): Unit = ???  // 编译报错
    
  2. 传递数组给变参如果已有一个数组,想将其元素作为变参传递,需要在数组后加 : _* 进行转换(告诉编译器 “将数组拆分为单个元素”):

    val nums = Array(1, 2, 3, 4)
    sum(nums: _*)  // 等价于 sum(1, 2, 3, 4),结果:10
    

    若直接传递数组(不加 : _*),会被当作单个参数(数组类型),导致类型不匹配:

    scala

    sum(nums)  // 编译报错:类型不匹配(需要 Int,找到 Array[Int])
    
  3. 变参与默认值参数的配合变参可以和带默认值的参数一起使用,但变参仍需放在最后:

    // 带默认值的参数在前,变参在后
    def log(level: String = "INFO", messages: String*): Unit = {
      println(s"[$level]: ${messages.mkString("; ")}")
    }
    
    log(messages = "start", "end")  // 输出:[INFO]: start; end
    log("ERROR", "file not found")  // 输出:[ERROR]: file not found
    
  4. 变参的本质是 Array函数内部,变参参数的类型是 Array[T]T 是参数声明的类型),因此可以使用数组的所有方法(如 foreachmaplength 等):

    def join(strs: String*): String = {
      strs.mkString("-")  // 使用 Array 的 mkString 方法
    }
    
    join("a", "b", "c")  // 结果:"a-b-c"