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

