`struct{}`和`struct{}{}`在Go语言中的作用是什么?

huangapple go评论147阅读模式
英文:

How do struct{} and struct{}{} work in Go?

问题

“struct{}”和“struct{}{}”在Go语言中的含义是什么?以下是一个示例:

array[index] = struct{}{}

或者

make(map[type]struct{})
英文:

I am wondering what does "struct{}" and "struct{}{}" mean in Go? An example is as follows:

array[index] = struct{}{}

or

make(map[type]struct{})

答案1

得分: 43

struct 是 Go 语言中的一个关键字。它用于定义结构体类型,结构体类型是一系列具有名称的元素。

例如:

type Person struct {
    Name string
    Age  int
}

struct{} 是一个具有零个元素的结构体类型。通常在不需要存储任何信息时使用。它的好处是大小为0,因此通常不需要内存来存储 struct{} 类型的值。

另一方面,struct{}{} 是一个复合字面量,它构造了一个 struct{} 类型的值。复合字面量可以构造结构体、数组、映射和切片等类型的值。它的语法是类型后跟花括号中的元素。由于“空”结构体(struct{})没有字段,元素列表也为空:

struct{}  {}
|  ^     | ^
  类型     空元素列表

举个例子,让我们在 Go 中创建一个“集合”。Go 没有内置的集合数据结构,但它有内置的映射(map)。我们可以将映射用作集合,因为映射只能有一个给定键的条目。由于我们只想在映射中存储键(元素),我们可以选择将映射的值类型设为 struct{}

一个具有 string 元素的映射:

var set map[string]struct{}
// 初始化集合
set = make(map[string]struct{})

// 向集合中添加一些值:
set["red"] = struct{}{}
set["blue"] = struct{}{}

// 检查一个值是否在映射中:
_, ok := set["red"]
fmt.Println("Is red in the map?", ok)
_, ok = set["green"]
fmt.Println("Is green in the map?", ok)

输出结果(在 Go Playground 上尝试):

Is red in the map? true
Is green in the map? false

请注意,当将映射创建为集合时,使用 bool 作为值类型可能更方便,因为检查元素是否在其中的语法更简单。有关详细信息,请参阅这里

英文:

struct is a keyword in Go. It is used to define struct types, which is a sequence of named elements.

For example:

type Person struct {
    Name string
    Age  int
}

The struct{} is a struct type with zero elements. It is often used when no information is to be stored. It has the benefit of being 0-sized, so usually no memory is required to store a value of type struct{}.

struct{}{} on the other hand is a composite literal, it constructs a value of type struct{}. A composite literal constructs values for types such as structs, arrays, maps and slices. Its syntax is the type followed by the elements in braces. Since the "empty" struct (struct{}) has no fields, the elements list is also empty:

 struct{}  {}
|  ^     | ^
  type     empty element list

As an example let's create a "set" in Go. Go does not have a builtin set data structure, but it has a builtin map. We can use a map as a set, as a map can only have at most one entry with a given key. And since we want to only store keys (elements) in the map, we may choose the map value type to be struct{}.

A map with string elements:

var set map[string]struct{}
// Initialize the set
set = make(map[string]struct{})

// Add some values to the set:
set["red"] = struct{}{}
set["blue"] = struct{}{}

// Check if a value is in the map:
_, ok := set["red"]
fmt.Println("Is red in the map?", ok)
_, ok = set["green"]
fmt.Println("Is green in the map?", ok)

Output (try it on the Go Playground):

Is red in the map? true
Is green in the map? false

Note that however it may be more convenient to use bool as the value type when creating a set out of a map, as the syntax to check if an element is in it is simpler. For details, see https://stackoverflow.com/questions/33207197/how-can-i-create-an-array-that-contains-unique-strings/33207265#33207265.

答案2

得分: 11

如izca所指出的:

Struct是一个用于定义结构类型的Go关键字,它只是由你决定的任意类型的变量组成的用户定义类型。

type Person struct {
    Name string
    Age  int
}

结构体也可以是空的,不包含任何元素。但是Struct{}{}有不同的含义。这是一个复合结构体字面量,它内联定义了一个结构体类型,并定义了一个结构体并不赋予任何属性。

emptyStruct := Struct{} // 这是一个非法操作
// 你定义了一个没有类型的内联结构体字面量
// 对于下面的情况也是一样的

car := struct{
          Speed  int
          Weight float
       }
// 你定义了一个结构体,但没有创建实例并赋值给car
// 然而下面的情况是完全有效的

car2 := struct{
          Speed  int
          Weight float
       }{6, 7.1}

// car2现在具有速度6和重量7.1

这里的代码创建了一个空结构体字面量的映射这是完全合法的

```go
make(map[type]struct{})

它与以下代码等效:

make(map[type]struct{
        x int
        y int
     })
英文:

As pointed out by izca:

Struct is a go keyword for defining struct types which are just user defined types composed of variables of whatever arbitrary type you decide.

type Person struct {
    Name string
    Age  int
}

Structs can also be empty with Zero elements.
However Struct{}{} has a different meaning. This is a composite struct literal. It inline defines a struct type and defines an struct and assigns no property.

emptyStruct := Struct{} // This is an illegal operation
// you define an inline struct literal with no types
// the same is true for the following

car := struct{
          Speed  int
          Weight float
       }
// you define a struct be do now create an instance and assign it to car
// the following however is completely valid

car2 := struct{
          Speed  int
          Weight float
       }{6, 7.1}

//car2 now has a Speed of 6 and Weight of 7.1

This line here just creates a map of empty struct literals which is perfectly legal.

make(map[type]struct{})

It is the same as

make(map[type]struct{
        x int
        y int
     })

huangapple
  • 本文由 发表于 2017年7月16日 05:29:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/45122905.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定