【Go】空结构体赋值问题

点击阅读更多查看文章内容

结构体空值 {} 赋值问题

问题描述:

t1 := make(map[string]struct{}) 定义了一个map,随后使用 t1[“a”] = struct{}{} 为a赋值一个空结构体

t2 := map[string]struct{}{“a”: {}} 初始化一个结构体,为a赋值{}

以上代码都是为a赋值一个空结构体,但是第一种方法必须使用struct{}{}来表示空结构体,如果仅使用{}则会报错,但是第二种方法可以使用{}来表示空结构体

1
2
3
4
5
6
7
8
9
10
11
12
package main

import "fmt"

func main() {
t1 := make(map[string]struct{})
t1["a"] = struct{}{}
fmt.Println(t1)

t2 := map[string]struct{}{"a": {}}
fmt.Println(t2)
}

为什么 t["a"] = {} 会报错

1
2
t := make(map[string]struct{})
t["a"] = {} // 错误:不能直接使用 `{}` 赋值

原因:

  • 如果只使用 {} 的话,Go 无法推断 {} 的类型,例如 {} 还可以表示空的数组,空的切片等。Go 在编译时必须知道你赋值的值的具体类型,而 {} 本身没有明确的类型信息。所以使用 struct{}{} 来显示地创建一个空结构体值。

  • struct{}{} 是一个类型化的空结构体字面量。其中struct{}表示一个没有任何字段的结构体的类型,struct{}{}则是这个结构体的一个实例,它明确指定了创建一个空的 struct{} 类型的值。

为什么 t2 := map[string]struct{}{"a": {}} 可以正常工作:

1
t2 := map[string]struct{}{"a": {}}  // 正确:可以直接使用 {}

这里初始化了一个 map 并在字面量中直接指定了值。Go 语言支持这种方式直接初始化 map。在这种情况下,Go 可以推断 {} 的类型是 struct{},因为已经在 map 的类型中明确了值的类型是 struct{}。这是 Go 的语法糖,允许在初始化 map 时直接使用空结构体 {}Go 会自动推断出它是 struct{} 类型的

空结构体的作用

在map中将值的类型设置为空结构体struct{},空结构体在 Go 语言中占用零字节的存储空间,因此在内存使用方面非常高效。当你只需要存储键而不需要关联任何值时,使用空结构体作为值类型是一种常见的做法。(其他类型比如指针即使赋空值nil,它本身仍是一个指向 nil 的指针,通常占用 8 字节(在 64 位系统上))

总结:

单纯使用{}不能明确表示到底是什么类型,空结构体?空切片?空数组?,因此当要表示空结构体时需要明确指定类型为 struct{}{}

作者

ShiHaonan

发布于

2025-03-03

更新于

2025-03-20

许可协议

评论