Please visit Go 101 for more articles on Go language.

One day, I googled a Go problem and Google guided me to the Go FAQ page. After having my problem solved, I read the whole FAQ.

There's a lot of history on that topic. Early on, maps and channels were syntactically pointers and it was impossible to declare or use a non-pointer instance. Also, we struggled with how arrays should work. Eventually we decided that the strict separation of pointers and values made the language harder to use. Changing these types to act as references to the associated, shared data structures resolved these issues. This change added some regrettable complexity to the language but had a large effect on usability: Go became a more productive, comfortable language when it was introduced. It is a great reading, I learned many from the article. But I noticed there is a question, Why are maps, slices, and channels references while arrays are values? . It is answered as followings:

It is much surprising to me that the concept "reference type" is still used in Go official docs, as the concept "reference type" has been totally removed from Go spec since Apr 3rd, 2013. Now there are 10 "reference" words in Go spec, none of them represents the concept "reference type".

...that the strict separation of pointers and values made the language harder to use. ... Another surprise is this line: This answer views pointers and values as two incompatible concepts. However, Go spec views pointers as special values. Pointers are called "pointer values" in Go spec. Values just instances of types. Obviously, the definition in Go spec for the word "pointer" is better. I think using "pointer values and non-pointer values" would be better.

So, I think this answer brings much confusion to Go community. It conflicts with the current Go spec and breaks concept consistency.

Back to the first surprise, I think calling map/slice/channel values as reference values is totally unnecessary. Not only because the word "reference" is abused too much in the programming world, but also because map/slice/channel values are just usual normal values.

Type Family Type Declaration map struct { m *internalHashtable } channel struct { c *internalChannel } slice struct { array *internalArray len int cap int } Here are the the internal declarations for map/slice/channel types: Please note, the above declarations may be not exactly the same as the ones in the official or unofficial Go implementations. Go implementations may use pointers to represent map and channel values directly, but Go spec/compilers will never view them as pointers. So, you can safely view map/slice/channel types as pointer wrapper types as declared above without any problem.

From the above declarations, it is easily to get the conclusion that map/slice/channel are just struct types which contain one non-exported pointer field. Calling them as reference types is totally unnecessary.

Map and slice types really have one difference from general struct types. Unlike general struct types, for a map or slice type T , T{} is not the zero value of T . But this is a poor reason to split map or slice types into a new reference type category.

map/slice/channel values are just normal pointer wrapper struct values

all value assignments, including parameter passings etc, are shallow value copying (the value pointed by pointers will not be copied) By knowing following two rules in Go: gophers should clearly understand the dest and source map/slice/channel values in an assignment will share the same underlying data pointed by the wrapped pointer.

Concepts are used to help programmers understand the mechanism of a language, not to confuse them. The concepts of values, pointer values and non-pointer values are sufficient for gophers to understand Go.

I hope Go docs don't break the consistency on concept definitions.