One day, I googled a Go question and Google directed me to the Go FAQ page. After the problem was solved, I read the entire FAQ.

It was a great read and I learned a lot from the article. But I noticed a problem. Why are arrays values and map, Slice, and channel references? The replies are as follows:

This topic has a long history. In the early days, map and channel were syntactic Pointers and could not declare and use non-pointer instances. In addition, we are doing our best to explore how arrays work. Ultimately, we believe that the strict separation of Pointers and values makes the language harder to use. Changing these types to references to associated shared data structures solves these problems. The change added some unfortunate complexity to the language, but it had a big impact on usability: Go became a much more efficient and comfortable language once it was introduced.

To my surprise, the Go official documentation still uses the concept of “reference types,” since the concept has been completely removed from the Go specification since April 3, 2013. There are now 10 “reference” words in the Go specification, none of which represents the concept of “reference type.”

Another surprise was this sentence:

. The strict separation of Pointers and values makes the language harder to use. .

This response treats Pointers and values as incompatible concepts. However, the Go specification treats Pointers as special values, and Pointers are called “pointer values.” A value is simply an instance of a type. Obviously, the term “pointer” is well defined in the Go specification. I think it would be better to use “pointer and non-pointer values”.

So, I think this response created a lot of confusion in the Go community. It conflicts with the current Go specification and breaks conceptual consistency.

Returning to the first surprise, I don’t think it’s necessary to call map/slice/channel values reference values at all. Not only is the word “reference” overused in the programming world, but map/slice/channel values are just normal values

The following is an internal declaration of the map/slice/channel types:

Type Family Type Declaration
map struct {

m *internalHashtable

}
channel struct {

c *internalChannel

}
slice struct {

array *internalArray

len   int

cap   int

}

Please note that the statements above may not be exactly the same as those in official or unofficial Go implementations. Go implementations can directly use Pointers to represent the values of map and channel, but the Go specification/compiler will never treat them as Pointers. Therefore, you can safely treat the Map /slice/channel type as the pointer wrapper type declared above without any problems.

From the above declaration, it is easy to conclude that map/slice/channel is just a structure type containing a non-exported pointer field. Calling them reference types is completely unnecessary.

Map and Slice types do have one difference from generic structural types. Unlike general structural types, T{} is not a zero value of T for map or slice type T. But that’s not a good reason to split a Map or Slice type into a new reference type category.

By understanding the following two rules of Go:

  • The map/slice/channel values are just plain pointer wrapper values
  • All assignments, including parameter passing, are shallow copies (Pointers to values are not copied)

Gopher should clearly understand that the DEST and source map/slice/channel values in an assignment will share the same underlying data that the wrapped pointer points to.

Concepts are mechanisms that help programmers understand the language, not confuse them. The concepts of values, pointer values, and non-pointer values were enough for Gopher to understand Go.

I hope the Go documentation doesn’t break the consistency of the concept definition.

Original: www.tapirgames.com/blog/golang…