
Go 允许在初始化指针切片时省略 & 和结构体类型名,编译器会根据切片元素类型自动推导并补全取地址操作,这是 Go 语言规范中定义的复合字面量简写规则。
go 允许在初始化指针切片时省略 `&` 和结构体类型名,编译器会根据切片元素类型自动推导并补全取地址操作,这是 go 语言规范中定义的复合字面量简写规则。
在 Go 中,当你声明一个指针切片(如 []*index)并使用复合字面量初始化时,编译器会依据目标元素类型进行智能推导。例如以下代码可正常编译运行:
type index struct {
i, j int
}
func main() {
indices := []*index{{0, 1}, {1, 3}} // ✅ 合法:自动补为 &index{0, 1}, &index{1, 3}
fmt.Println(*indices[1]) // 输出 {1 3}
}
这之所以可行,是因为 Go 语言规范(Composite literals)明确规定:
“在数组、切片或映射类型的复合字面量中,若其元素(或键)本身也是复合字面量,且该元素类型与容器的元素类型完全一致,则可省略内部字面量的类型;同理,若容器元素类型为 `T
,则地址操作符&和类型T` 也可一并省略。”*
换句话说,[]*index 明确告知编译器:每个元素都必须是 *index 类型。因此 {0, 1} 被自动解释为 &index{0, 1},无需显式书写 &index。
⚠️ 注意事项:
- 此简写仅适用于元素类型严格匹配的情况。一旦类型不一致,就必须显式写出完整形式。例如:
var indices []interface{} = []interface{}{&index{0, 1}, &index{1, 3}} // ✅ 必须写 &index // 不能写作 []interface{}{{0, 1}, {1, 3}} —— 编译失败:无法推导 interface{} 的底层类型 - 若结构体字段较多或含嵌套,仍建议优先保证可读性,必要时显式写出
&T{...}。 - 该规则同样适用于数组和 map 的键/值(如
map[string]*index{"a": {0,1}})。
总结:这一特性并非语法糖的“魔法”,而是 Go 类型系统在复合字面量上下文中实施的类型驱动简化规则,它减少了冗余,同时保持了类型安全——既提升了代码简洁性,又未牺牲明确性。熟练掌握它,能让 Go 初始化逻辑更干净、更地道。










