In a recent
post criticizing Go, which was issued for a translation, the user tucnak, in addition to being too familiar with Rob Pike, raised some interesting points about the language. Since the format of the article suggested, alas, not a desire to understand the topic, but to kindle holivary, I suggest in this article to go through the voiced "problems" and understand what it really is, and what makes modern companies choose Go.

Reason number 1. Manipulations with slices are just disgusting.
The author begins his separation of the language design with the assertion that negative indexes, as in Python, do not work.
// numbers [: - 1] from Python will not roll.
Here the answer is simple - Go is not Python, these are different languages. It is difficult for some people to be given the fact that no languages ​​other than Python are Python, but let's examine the question in more detail. Here is the
official answer of Robert Pike about why there are no negative indices in Go:
This was intentionally removed, because the expression s [i: j] can silently give an incorrect result if j becomes less than zero. That was the reason for the terrible bug in Rietveld, by the way. Indices should not be negative.
')
The issues on Github have a similar
question and answer , which complements the following statement:
This feature (present in Python, for example) is intentionally absent.
Arithmetic with indices in slices can lead to problems if the erroneous negative result "just worked", as a reverse index. This leads to intricate bugs.
In addition, from the status quo, the readability wins. Now it is obvious that the expression s [: i] creates a slice from s with a length of i bytes. If i can be negative, then more context is needed to understand the entire slice expression.
This decision is repelled by the general philosophy of Go to avoid subtle syntactic tricks.
We can agree that for some people a negative index for his cases can be convenient, and a bit shorter in the record. But the authors of Go, based on their more than half a century of development experience, see that this saving of several bytes in one case, leading to complex bugs and poor readability in the other, is not worth it, and they choose a solution that is more appropriate for the language concept. A solution that requires Python programmers to re-use a little, but reduces the risk of tricky errors in long term. It is clear that not everyone thinks for a long term, hence the confusion.
Go ahead, the following author's rant:
/ Want to insert some number? Nothing wrong,
// Go is generally accepted best practice!
numbers = append (numbers [: 2], append ([] int {3}, numbers [2:] ...) ...)
Firstly, this is not best practice, but a one-liner snippet found on the Go
Slice Tricks page. In real code, if anyone does, it is more readable. And here we, for a start, remember that the design of slices and arrays in Go was discussed for more than a year before we come to the final design. And the main factors were “practical necessity” and “speed”. Yes, this is not a very familiar approach, in many other languages ​​the presence of features in a higher priority, but in Go like this.
And now let's ask the author two questions:
- How frequent is inserting an element in the middle of an array?
- How effective is an insert in the middle of the array?
I think it is not worth explaining that with the current implementation (arrays in Go are very similar to arrays in C, and basically serve as a repository for slices) this insert is a rather expensive operation, forcing (re) to allocate memory, and the actual use case of this not as frequent as, say, “adding” an element to a slice.
It really is not a frequent case, at least in the niche that Go is designed for. Of course, there are such cases - for example, operations with binary protocols, but this is not something that you will write at least once a day or even once a month. In the comments to the post of the author, I asked at least one person to give three examples from my real code, where he would need to insert an element in the middle of the array - no one wrote. But they wrote invented cases in which it is much more correct to use not arrays, but more suitable data structures.
Summarizing, such a design was chosen intentionally, to create an incentive to correctly use data structures, and not to receive a legacy in the form of a braked software in a long term. Again, we see this “long term” hated by many here, which spoils the whole story.
I will not go through the rest of the comments on the slices, they are there at the level of “but in Spanish they write the letter H - see how awful it is”.
Reason number 2. Zero interfaces are not always zero :)
This is a classic example of
cherry-picking - the author finds on the Internet an example of code that can confuse a beginner who is not familiar with Go interfaces (I suppose most readers of the previous article), and exposes this example as “bad design”. Behind the scenes, of course, remains that this moment is devoted to an
entry in the FAQ on the Go page, that you will never encounter this problem in real code (unless you get a completely innocent junior), and that the design of the type and interface system its simplicity and integrity allows you to create complex abstractions without the use of classes and inheritance. All this passes by the author and his readers, who
write with delight “at last a post of hate about Go”.
Interfaces are a rather unique concept in Go, and many newbies need a little (but, indeed, “little”) time to understand them. And the concept of a nil interface, too. This is not a reason to ignore the power of the concept and call it a bad design. Go and so does too much to the entrance was quick and painless, but to require from him zero effort to understand new concepts - stupid.
Summary - the interface design is great, and is based on hundreds of trade-offs from areas that the average programmer hasn’t even heard of. In any design there will always be small or not so things that can be confusing at first. But in Go, this is the only little thing that you will most likely never encounter in practice, and if you do, you will quickly find the answer in the official FAQ, and you will never make a mistake again. Few languages ​​can boast of such, and this is one of the clear evidence that Go design is thought out more than excellent.
Reason number 3. Fun variable hiding
Here the author deceives both readers and himself. First, shadowing has always been the source of
various confucias and
misunderstandings , and Go, unlike, say C ++, does not have undefined behavior when hiding variables. You can only blame the inattention of the programmer, which, of course, does not remove from the language of responsibility in helping the programmer not to make such mistakes.
Secondly, the criticism of the “design of hiding variables” should imply the proposal of an alternative, more successful design - then the discussion has a chance to be substantive.
Thirdly, the regular
go vet utility is able to show hidden declarations of variables, but since concealment is not an error, by default this go vet flag is turned off so as not to clutter the output with the correct code.
Use
go tool vet -shadow=true
.
, go vet :
$ go tool vet -shadow=true main.go
main.go:16: declaration of number shadows declaration at main.go:10:
, — , , .
, Go, , , Go, .
â„–4. []struct []interface
, Go, . , , -, .
, , , , , « Go » (),
.
, — «» «» Go. , , , «» . , , — .
— — , — . O(n) Go , . — , , , . , Go long term. , , .
№5. « »
,
range , , , ,
range — foreach ++
, , , , .
? Go — , C++. Go Python, C++ — .
, go-tour ":=", :
for number := range numbers {}
, , range , foreach, . , . « » — , .
â„–6.
, , Go . , , opinionated Go , , FAQ,
. , /C++, , , 5-10 , . , — , Go- , ++- , / « ». .
, , Go. . , , .
« , — = » , , .
â„–7. Go
Mozilla ( « , »), . :
, Go —
, , - -.
go generate , Make- , - yacc, thrift, protobuf swig. , , , , go generate (- hashbang). .
, . , , .
« , », «» « ».
Go — opinionated. Go , . — , — , — , — .
Go — , , . , , — , . , , , long-term short-term .
, Go - - , , . Go , . , , .
, «» — , , , . , , . , , , . , , Go , , , « REST- C++ 2 rock-star C++ » « Go » , , . , , , , « , ». .
, — , .