跳转到主要内容
模块 3 · 第 3 课(共 5)课程中的13/50~10 min
模块课程(3/5)

可变参数函数

可变参数函数接受任意数量的参数 相同类型。您可以通过在最后一个类型之前放置 ... 来声明它们 参数。在函数内部,参数是一个切片。

宣言

Go
func sum(nums ...int) int {
    tot := 0
    for _, n := range nums {
        tot += n
    }
    return tot
}

sum()              // 0   (nums = []int{})
sum(1)             // 1
sum(1, 2, 3, 4)    // 10

只有 last 参数可以是可变参数:

Go
func log(prefix string, values ...any) { ... }   // ok
// func wrong(...int, suffix string) {}            // ERRORE

摊开一片

如果您已经有一个切片,则可以将其传递给可变参数函数 ...:

Go
nums := []int{1, 2, 3}
sum(nums...)         // 6 — espande lo slice nei singoli argomenti

“...”位于切片之后。没有传播你会得到一个类型 错误:您将在函数需要序列的地方传递 []int int。

nums 是一个切片,而不是一个新容器

在函数 nums 内部,其类型为 []int。所有标准切片 操作工作:len(nums)、nums[0]、range 等。

经典用例:fmt.Println

所有 fmt 的 Print* 函数都是可变参数:

Go
// signature (semplificata):
// func Println(a ...any) (n int, err error)

fmt.Println("ciao", 42, true)
args := []any{"a", "b", "c"}
fmt.Println(args...)

尝试一下

锻炼#go.m3.l3.e1
尝试:0加载中...

定义 sum(nums ...int) int 返回所有参数的总和。

正在加载编辑器...
显示提示

函数“nums”内部的类型为“[]int”。

3 次尝试后可用的解决方案

锻炼#go.m3.l3.e2
尝试:0加载中...

通过传递带有展开“nums...”的切片 nums 来调用现有的 sum 函数。

正在加载编辑器...
显示提示

`...` 位于切片名称之后。

3 次尝试后可用的解决方案

Quiz#go.m3.l3.e3
准备好

在 `func f(args ...string)` 中,`args` 是什么类型?

Go
func f(args ...string) {
    _ = args
}
答案选项

回顾

  • ...T 作为最后一个参数 = 可变参数函数;里面是[]T。
  • 使用单个值调用:编译器将它们收集到一个切片中。
  • 使用现有切片调用:slice...(扩展,重用切片)。
  • 所有 fmt.Print* 函数都是可变参数。
  • 只有最后一个参数可以是可变参数。