📜 ⬆️ ⬇️

Why in Go ampersand and asterisk (& and *)?

If you have ever been confused, which means the symbol "ampersand" ( & ) or "asterisk" ("multiplication sign", * ) or get confused when to use what, then this article is for you. The authors of Go tried to make the language familiar to most programmers, and many syntax elements were borrowed from C. But in 2017 it is already difficult to understand, most programmers have C or not, and I dare to believe that they no longer exist. Therefore, concepts well known to the past generation of developers may look like a perfect abracadabra for the new generation. Let's dig a little history and dot the i's about indexing questions in Go and using the characters & and * .



Pointers


About what is and how the pointers are arranged, I wrote in the article "How not to step on a rake in Go" , which I recommend to read even to novices in Go. A brief repetition of pointers:


in fact, it is one block of memory that contains the address of another block of memory where the data resides. If you hear the phrase "dereference pointer", it means "to find the data from the memory block pointed to by this address."

Here is a visualization from the article:
image


Here Point{10, 20} is a "literal" - a new variable declared in place, a "memory block", and & is the "address of this memory block".


Ie in the code:


 var a int var b = &a fmt.Println(a, b) //  "0 0x10410020" 

the variable b will be a pointer and contain the address a .


Same code, but write type b explicitly:


  var a int var b *int = &a fmt.Println(a, b) //  "0 0x10410020" 

here the asterisk means "type pointer to number". But, if it is used not in front of the type, but in front of the variable itself, then the value is reversed - “value at this address”:


  var a int var b *int = &a var c int = *b fmt.Println(a, b, c) //  "0 0x10410020 0" 

This can be confusing and confusing, especially for people who have never worked with pointers that are not available, for example, in such popular languages ​​as JavaScript or Ruby. Moreover, in languages ​​like C and C ++, there are still a lot of uses for pointers, for example, pointer arithmetic, which allows you to run directly and implement incredibly fast data structures using modern data shifts. It is also very convenient to get a buffer overflow due to this, creating bugs that cause damage to billions of dollars. There are even whole books on how to understand pointers in C.


But if the mechanics of working with pointers in Go are relatively simple, the question remains - why is ampersand and asterisk - what does this even mean? Perhaps this is because the characters next to the keyboard ( Shift-7 and Shift-8 )? Well, to understand any topic, there is no better way than digging its story.


Story


And the story is. One of Go's authors was legendary Ken Thompson , one of the pioneers of computer science who gave us a regular expression, UTF-8 and the programming language B , from which C emerged, on the basis of which Go appeared 35 years later. In general, Go genealogy is a bit more complicated, but C was taken as a basis for the simple reason that it was a language that for decades was the standard for studying programming in universities, and I don’t need to talk about its popularity at the time.


And although now Ken Thompson has departed a bit from Go and is flying his private jet, his decisions have penetrated Go long before Go. In his youth, he was entertained by the fact that he wrote new programming languages ​​for breakfast (I slightly exaggerate), and one of the languages ​​he created along with yet another computer science legend Denis Ritchie was B (B) .


At that time, Ken Thompson wrote an assembler operating system for the PDP-7 computer , which cost 72,000 dollars - which is about half a million dollars today - had a memory of 9 KB (expanded to 144KB) and looked like this:



Actually, this operating system was called Unics, and then it was renamed UNIX. And when it came to rewriting it for the new cool computer PDP-11 , it was decided to write in some higher-level programming language. BCPL , which was the predecessor of B, was too verbose - many letters. B was more concise, but had other problems that made him a bad candidate for porting UNIX to the PDP-11. It was then that Denis Ritchie began working on a new language, based in large part on B, specifically for writing UNIX under PDP-11. The name C was chosen as the next letter of the alphabet after B.


But back to the topic of the ampersand and the asterisk. The asterisk ( * ) was still in the BCPL language, and it got into B with the same meaning of the pointer designation, simply because it was so in BCPL. Exactly for the same reason, migrated to S.


But an ampersand (&), meaning "variable address", appeared in B (and also migrated to C simply because), and was chosen for several reasons:



If I have confused you, then that's clearer:


And here you need to look carefully at the keyboard of the time. Slightly higher in the picture of the PDP-7, you can consider the input device, which was Teletype 33 . It is worth looking at his keyboard more closely to understand the realities of that time, and to understand the limitations that programmers and designers of programming languages ​​encountered at the time:



As you can see, there was neither a touchbar, nor an emodzhi :), and the characters had to be chosen only from the set that was in the teletype. It is also noteworthy that the ampersand and the asterisk were then not near, but by as many as 4 keys separately, which refutes the idea of ​​choosing an ampersand due to the proximity of the keys. Actually, of all the available keys, Ken Thompson at that moment liked the most “ampersand”, similar to the “address”.


Well, then you know - C became the language of the century (past), influenced a huge number of other languages, and books on C became the desktop bibles of programmers for several decades. In the same form, pointers with an asterisk and an ampersand hit C ++, another mainstream language, in which most of the network and server software was written before Go.


Therefore, the decision to include pointers (without pointer arithmetic, fortunately) in Go with the same syntax was logical and natural. For C / C ++ programmers, these are the same basic and simple concepts as { and } parentheses.


And yet it is surprising to realize what a strong influence historical decisions have taken on half a century ago on modern technologies.


Conclusion


If you are still insecure with pointers in Go, remember two simple rules:



I hope someone this will help a little better understand the meaning of pointers and symbols behind them in Go.


')

Source: https://habr.com/ru/post/339192/


All Articles