在 Go 语言中,...
(三个点)是一个多功能的符号,具体用法根据上下文的不同而变化。以下是其核心用法及示例详解:
1. 可变参数函数(Variadic Functions)
用于定义和调用接受不定数量参数的函数。
定义可变参数函数
// 定义:参数类型前加 ... 表示接受任意数量的该类型参数
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
调用函数
// 传递多个参数
fmt.Println(sum(1, 2, 3)) // 输出 6
// 传递切片(需用 ... 展开)
nums := []int{4, 5, 6}
fmt.Println(sum(nums...)) // 输出 15
注意:
- 可变参数必须是函数的最后一个参数。
- 参数在函数内部以切片形式处理(如
numbers
的类型是[]int
)。
2. 数组/切片字面量的长度推断
用于声明数组时让编译器自动计算长度。
数组长度自动推导
// 编译器根据元素数量推断数组长度
arr := [...]int{1, 2, 3} // 类型为 [3]int
fmt.Printf("数组长度:%d\n", len(arr)) // 输出 3
切片初始化(与数组区别)
// 切片不需要指定长度
slice := []int{1, 2, 3} // 类型为 []int
3. 切片展开(Unpacking Slices)
在函数调用时将切片展开为独立参数。
示例:合并多个切片
s1 := []int{1, 2}
s2 := []int{3, 4}
// 使用 ... 展开切片
combined := append(s1, s2...)
fmt.Println(combined) // 输出 [1 2 3 4]
关键点:
- 仅适用于将切片展开为函数参数。
- 类型必须匹配(如
s2
必须是[]int
才能展开到append
)。
4. 接口断言中的类型匹配(Go 1.18+ 泛型)
在泛型编程中用于类型约束(Go 1.18 引入泛型后新增)。
泛型类型约束
// 定义泛型函数,T 可以是任何实现了 String() 方法的类型
type Stringer interface {
String() string
}
func PrintAll[T Stringer](values ...T) {
for _, v := range values {
fmt.Println(v.String())
}
}
5. 其他场景
结构体字面量的键值对展开(Go 1.18+ 实验特性)
type Point struct{ X, Y int }
// 使用 ... 展开结构体字段(实验性语法,需确认版本支持)
p := Point{...Point{X: 1}, Y: 2} // 等价于 Point{X: 1, Y: 2}
总结表格
场景 | 用法说明 | 示例 |
---|---|---|
可变参数函数定义 | 表示接受多个同类型参数 | func sum(nums ...int) int |
切片展开调用 | 将切片解包为独立参数 | sum(slice...) |
数组长度推断 | 自动计算数组长度 | arr := [...]int{1, 2, 3} |
泛型类型约束 | 匹配满足接口的所有类型(Go 1.18+) | func PrintAll[T any](v ...T) |
结构体展开(实验性) | 合并结构体字段 | Point{...p, Y: 2} |
注意事项
- 类型安全:展开切片时,类型必须与目标参数匹配。
- 性能:频繁使用可变参数可能影响性能(涉及切片内存分配)。
- 可读性:合理使用
...
,避免过度复杂化代码逻辑。
通过灵活运用 ...
,可以简化代码并增强灵活性,但需注意上下文语义的差异!