# Composite literals

### September 20, 2023

Earlier this year, near the beginning of this series on the Go spec, we went through literal representations of all of the basic types in Go: `int`s, `string`s, etc.

If this were an Intro to Go style book, the very next section would have been on composite literals. But it’s not. So we had to wait nearly 6 months to get to that topic… But here we are, at long last!

## Composite literals

Composite literals construct new composite values each time they are evaluated. They consist of the type of the literal followed by a brace-bound list of elements. Each element may optionally be preceded by a corresponding key.

``````CompositeLit  = LiteralType LiteralValue .
LiteralType   = StructType | ArrayType | "[" "..." "]" ElementType |
SliceType | MapType | TypeName [ TypeArgs ] .
LiteralValue  = "{" [ ElementList [ "," ] ] "}" .
ElementList   = KeyedElement { "," KeyedElement } .
KeyedElement  = [ Key ":" ] Element .
Key           = FieldName | Expression | LiteralValue .
FieldName     = identifier .
Element       = Expression | LiteralValue .
``````

The LiteralType’s core type `T` must be a struct, array, slice, or map type (the syntax enforces this constraint except when the type is given as a TypeName).

So here we have the technical definition of a composite literal, and the more human readable explanation: A composite literal in Go is an expression that evaluates to a composite value. A composite value, in turn, is a type with a core type of struct, array, slice, or map.

There’s one caveat here, mentioned in parenthesis. When we’re using a composite type directly, the syntax itself enforces compliance with this rule.

``````var x = map[string]string{"a": "b"}
``````

The ambiguity arises when using named types:

``````type Foo map[string]string
type Bar int

var x = Foo{"a": "b"} // Completely valid
var y = Bar{"a": "b"} // Syntactically valid, but logically incorrect, because named type Bar does not have a composite core type.
``````

Quotes from The Go Programming Language Specification Version of August 2, 2023