Go Playgroud: https://play.golang.org/p/DNJ0Q9YrE14

var nilSlice []int emptySlice := []int{}

相同点

len(s)

len(nilSlice) == 0 // true len(emptySlice) == 0 // true

cap(s)

len(nilSlice) == 0 // true len(emptySlice) == 0 // true

不同点

s == nil ?

nilSlice == nil // true emptySlice == nil // false

json.Marshal

json.Marshal(nilSlice) // null json.Marshal(emptySlice) // []

json.Unmarshal

{} Unmarshal 后得到 nil slice; {"arr": null} Unmarshal 后得到 nil slice; // 如果是HTTP API, 则服务端无法知道客户端是未传arr字段还是传了一个null; {"arr": []} Unmarshal 后得到 empty slice;

如何检测是否是 nil slice

虽然 nilSlice == nil, 但换一种场景却无法判断:

var i interface{}
i = nilSlice

i == nil // false, 原因见: https://github.com/isayme/blog/issues/25

这里引入 stretchr/testify:IsNil 中的方法:

// IsNil 判定是否是 nil, 支持 pointer/channel/map/slice
func IsNil(v interface{}) bool {
	if v == nil {
		return true
	}

	value := reflect.ValueOf(v)
	kind := value.Kind()
	if kind >= reflect.Chan && kind <= reflect.Slice {
		return value.IsNil()
	}

	return false
}

参考资料