kayak
kayak

Reputation: 139

What are the second pair of braces in this Golang struct?

var cache = struct    {
    sync.Mutex
    mapping map[string]string
} {
    mapping: make(map[string]string),
}

This looks like a struct with an embedded field sync.Mutex but I can't get my head around the second set of braces. It compiles and executes but what's up? Why does the label on the make instruction matter (it does) and the comma? Thanks...

Upvotes: 13

Views: 3488

Answers (2)

user1087001
user1087001

Reputation:

This is called a "struct literal" or an "anonymous struct" and is, in fact, how you always create structs in Go, it just may not be immediately obvious since you might be used to creating new types for struct types to make declaring them a bit less verbose.

An entire struct definition is actually a type in Go, just like int or []byte or string. Just as you can do:

type NewType int
var a NewType = 5 // a is a NewType (which is based on an int)

or:

a := 5 // a is an int

and both are distinct types that look like ints, you can also do the same thing with structs:

// a is type NewType (which is a struct{}).
type NewType struct{
  A string
}
a := NewType{
  A: "test string",
}

// a is type struct{A string}
a := struct{
  A string
}{
  A: "test string",
}

the type name (NewType) has just been replaced with the type of the struct itself, struct{A string}. Note that they are not the same type (an alias) for the purpose of comparison or assignment, but they do share the same semantics.

Upvotes: 2

Christian Grabowski
Christian Grabowski

Reputation: 2882

The example you have is equivalent to:

type Cache struct {
    sync.Mutex
    mapping map[string]string
}

cache := Cache{
    mapping: make(map[string]string),
}

Except in your example you do not declare a type of Cache and instead have an anonymous struct. In your example, as oppose to my Cache type, the type is the entire

struct {
    sync.Mutex
    mapping map[string]string
}

So think of the second pair of braces as the

cache := Cache{
    mapping: make(map[string]string),
}

part.

make is a built in function that works similarly to C's calloc() which both initialize a data structure filled with 0'd values, in Go's case, certain data structures need to be initialized this way, other's (for the most part structs) are initialized with 0'd values automatically. The field there is needed so that the compiler now's cache.mapping is a empty map[string]string.

The comma there is part of Go's formatting, you can do Cache{mapping: make(map[string]string)} all on one line, but the moment the field's assignment is on a different line than the opening and closing braces, it requires a comma.

Upvotes: 11

Related Questions