Should You Return Empty or Nil Slices in Go?
Tags: cleancode, engineeringpractices, go, languages
Published: 2020-09-14 13:20:15

---
title: Should You Return Empty or Nil Slices in Go?
published: true
date: 2020-09-03 13:05:21 UTC
tags: CleanCode,EngineeringPractices,Golang,Languages
canonical_url: https://qvault.io/2020/09/03/should-you-return-empty-or-nil-slices-in-go/
---

 ![Empty vs Nil Slices in Go](https://qvault.io/wp-content/uploads/2020/09/Nil-vs-Empty-Slice-300x169.png "Nil vs Empty Slice")

The post [Should You Return Empty or Nil Slices in Go?](https://qvault.io/2020/09/03/should-you-return-empty-or-nil-slices-in-go/) first appeared on [Qvault](https://qvault.io).

In Go, we are often returning zero values. Idiomatic Go encourages the use of guard clauses, and [guard clauses](https://qvault.io/2019/08/16/guard-clauses-how-to-clean-up-conditionals/) necessitate the need to return early. When returning early with an error, by convention all other return values should be zero values. The confusion arises with data types like maps and slices… should they be nil, or should they be empty?

The question is, should we use this syntax:

```go
func getItems(url string) ([]string, error) {
	data, err := makeRequest(url)
	if err != nil {
		return nil, err
	}
	items, err := unpack(data)
	if err != nil {
		return nil, err
	}
	return data, nil
}
```

or this syntax?

```go
func getItems(url string) ([]string, error) {
	data, err := makeRequest(url)
	if err != nil {
		return []string{}, err
	}
	items, err := unpack(data)
	if err != nil {
		return []string{}, err
	}
	return data, nil
}
```

## The Differences

I ran a quick bit of code to show some of the differences between nil and empty slices:

```go
package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	var nilSlice []string
	fmt.Println(nilSlice) // Output: []
	fmt.Println(len(nilSlice), cap(nilSlice)) // Output: 0 0
	fmt.Println(nilSlice == nil) // Output: true
	dat, _ := json.Marshal(nilSlice)
	fmt.Println(string(dat)) // Output: null

	emptySlice := []string{}
	fmt.Println(emptySlice) // Output: []
	fmt.Println(len(emptySlice), cap(emptySlice)) // Output: 0 0
	fmt.Println(emptySlice == nil) // Output: false
	dat, _ = json.Marshal(emptySlice)
	fmt.Println(string(dat)) // Output: []
}

```

As you can see there are some similarities between nil and empty slices:

- Both have zero length and cap
- Both print `[]`
- Both can be used the _same way_ in range loops and append functions (not shown here)

They differ in the following ways:

- Only the nil slice will success a nil check
- When encoded as JSON using the standard library, the nil slice becomes `null` and the empty slice becomes `[]`

## Which Should I Do?

**Generally speaking, prefer nil**.

According to the [Go wiki](https://github.com/golang/go/wiki/CodeReviewComments#declaring-empty-slices), nil is the preferred style. When we just need to return an empty slice `nil` will work great in practically all cases. It’s also easier to type `nil` than `[]string{}` or `make([]string, 0)` and typically gets syntax highlighted which makes it easier to read.

## Thanks For Reading!

Follow us on Twitter [@q\_vault](https://twitter.com/q_vault) if you have any questions or comments

Take some [coding courses on our new platform](https://app.qvault.io)

[Subscribe](https://mailchi.mp/5c7f5c281bbe/qvault-newsletter-subscribe) to our Newsletter for more programming articles