liveBook · Manning

Make

As explained in Go in Action, Second Edition

make is a Go built-in function that allocates and initializes slices, maps, or channels with a specified type and size parameters.

Use Go’s built-in make when a slice, map, or channel needs to be ready for use. For slices, it sets the initial length and can reserve capacity for later growth. For maps, it avoids assigning into an uninitialized map. For channels, it creates a value that goroutines can use to communicate. section 4.2.2 section 4.3.1 section 9.4

For a slice, write make([]T, length) or make([]T, length, capacity). The first form creates a slice whose elements hold the zero value of T. The second reserves additional backing-array space for append without making those extra positions part of the current slice. Capacity must be at least length; an invalid value produces a compiler error when detectable, or a runtime panic otherwise. section 4.2.2

Start empty, with room to grow

items := make([]int, 0, 5) creates an empty slice with space reserved for five values. len(items) is 0; add values with append rather than indexing the reserved positions. section 4.2.2

Use make(map[int]string) for an initialized empty map. By contrast, var labels map[int]string leaves labels nil, and assigning labels[1] = "one" panics. An empty map literal also initializes the map; a populated literal is generally the preferred choice when starting with known key–value pairs. section 4.3.1

Channels put make to work in concurrent designs. A feed-ingestion function can create out := make(chan *gofeed.Article), pass it to a saving goroutine, send fetched articles, and close it when sending is complete. The consumer ranges over the channel until it is closed. A channel can also be returned from a function or stored in a struct; examples use make(chan string, 5) to give one a capacity. section 9.4

Listing 9.16 main.go: Passing a channel to another function
func fetchFeed(ctx context.Context, url string) (gofeed.Feed, error) {
 fmt.Println("fetching feed: ", url)
 fp := gofeed.NewParser()
 feed, err := fp.ParseURLWithContext(ctx, url)
 if err != nil {
    return gofeed.Feed{}, err
 }
 fmt.Println("fetched: ", url)
 out := make(chan *gofeed.Article) #1
 go saveFeed(out) #2
 defer close(out) #3
 for _, article := range feed.Article{
  fmt.Println("ingesting article: ", article.Link)
  out <- article #4
 }
 fmt.Println("processed: ", url)
 return feed, nil
}

The feed-ingestion listing shows channel creation in context: the producer sends articles to a saving function and closes the channel afterward. section 9.4

How Go in Action, Second Edition covers it

How deep it goes
Explains slice length, capacity, zero values, and backing storage; contrasts map initialization and demonstrates channel creation without detailing channel internals.
Examples
Shows zero-filled and preallocated slices, empty maps alongside a nil-map panic, and channels carrying feed articles and errors.
What it assumes
Assumes familiarity with Go types and goroutines while explaining slice allocation and the nil-map initialization hazard.
What you can do after
Build it from scratch: initialize Go collections and channels, reserve slice capacity, and avoid assignments into nil maps.
How it connects
Connects make to append, backing arrays, nil maps, map literals, channels, and goroutines.

Also explained in

Compare how 2 books explain make →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Action, Second Edition. The section links point to the parts of the book it draws on.