This is a creation in Article, where the information may have evolved or changed.
Transferred from: Http://blog.csdn.net/liigo
Several times, when I think about it, I always ask myself: why should I give up the go language? Is this the right decision? Is it sensible and rational? In fact, I have been seriously thinking about this problem.
To be straight to the point, I gave up the Go language (Golang) because of two "bad": first, the go language itself is not happy, second, to go language community of some people unhappy. There is no doubt that this is a very subjective conclusion. But I have an objective argument that is sufficiently detailed to support this seemingly subjective conclusion.
Section No. 0: My go language experience
Let me tell you about my experience to avoid being the low-level black of the go language for no reason.
At the end of 2009, the Go Language (Golang) first public release, shrouded in the "Google made" Halo, attracted a lot of early adopters, I (Liigo) also live in it, general read some of the Go language materials, learning the basic tutorial, Dissatisfied with the semicolon and braces in his grammar, he soon forgot, not taking it as a thing.
Two years later, at the end of 2011, the Go Language Release 1.0 program was put on the agenda, and the related reports came up again, and I followed it again, [re-evaluated][1] and decided to take a deep dive into the go language. I subscribed to the official e-mail groups of users, nuts, Dev, commits, and insisted on reading the email every day, as well as every source code update submitted by the developer, and submitted many improvements to go, even including [modifying the go language compiler source code][2] to participate directly in the development task. It lasted a few months.
By the beginning of 2012, the Go 1.0 release, the language and standard library have been basic stereotypes, there is no possible significant improvement, I am not in the go language before the 1.0 to a step forward, to achieve self-breakthrough, even with a lot of obvious flaws to 1.0, feel very disappointed, so gradually alienated it (so Go I seldom care about the things after 1.0). Later, I saw the release Note of Go 1.1 that was about to be released, and found that the language level had not changed much, but that it had been patched and improved at the library and tools level, and felt that it had lost its momentum of growth at a young age and was increasingly disappointed. And some of the people in the go language community, including some of Google's people who are responsible for developing the go language, have been extremely disgusted with their attitude, words and deeds, prompting me to abandon the go language.
[1]: Https://plus.google.com/+LiigoZhuang/posts/CpRNPeDXUDW
[2]: http://blog.csdn.net/liigo/article/details/7467309
1th: Why am I upset with the go language?
There are a lot of things that make me uncomfortable with the go language, and here is a list of some of the places I can remember now, which are basically in no particular order. After reading patiently, can the reader calmly say "I don't care"?
1.1 Do not allow left curly braces to start another line
About the placement of curly braces, in C, C + +, Java, C # and other communities, more than 10 years of continuous controversy, has never formed a consensus. In my opinion, this is the subjective tendency very heavy choice, does not violate the principle does not involve the right and wrong situation, should not engage in the fits, lets the programmer or the team own choice is enough. The programming language itself imposes restrictions, and it is not worth the candle to impose its own preferences on others. Whatever tends to be one of them, it is inevitable to offend a group of people against them. Although I am used to putting the left curly braces at the end of the line, I feel very uncomfortable when I think of being banned from other options. Go language This issue, did not do "unite all can unite the power" does not say, also intentionally gives oneself the enemy, too failed.
1.2 The compiler inexplicably adds a semicolon to the end of the line
For the go language itself, the semicolon at the end of the line can be omitted. However, in its compiler (GC) implementation, in order to facilitate the compiler developers, but in the lexical analysis phase forcibly added a line end of the semicolon, which in turn affects the language specification, "How to add a semicolon" to make special provisions. This kind of metamorphosis is unprecedented. In the case where the left curly brace is accidentally placed at the beginning of the next line, it automatically adds a semicolon at the end of the previous line, causing an inexplicable compilation error (before Go 1.0), even if it doesn't understand itself. If you do not handle the semicolon, simply do not omit the semicolon, or, Scala and JavaScript compiler is open source, and they learn how to deal with the omit line end semicolon can it?
1.3 Extreme emphasis on the speed of compilation, regardless of the function should be provided
The programmer is a person is not God, the coding process inevitably because of the carelessness or neglect to make some mistakes. Some of them, is the collective nature of the very easy to take the wrong (the Go language example I can not remember, C + + examples are "base class destructor is not virtual function"). At this time the compiler should stand out, do more checks, constraints, check the work, try to prevent the occurrence of regular errors, try not to let the potential error code compiled through, if necessary, give some warnings or hints, let the programmer pay attention to. compiler is not a machine, is not to do more dirty work dirty miscellaneous work, reduce the mental burden of people? The compiler does a lot of checking, it may avoid hundreds of thousands of of programmers in the next many years to make the same mistake countless times, save countless times, this is boundless beneficence good. But the authors of the go compiler don't think so, and they don't want to spend more hours adding new features to the compiler, feeling that it's a loss, but slowing down the compilation speed. They rejected a lot of requirements for compiler improvements by affecting compilation speed. A typical unworthy. The emphasis on compiling speed is commendable, but I don't approve of it if I give up the proper functionality.
1.4 Error handling mechanism too primitive
The basic pattern of handling errors in the go language is that functions typically return multiple values, where the last value is the error type, which is used to denote the extreme description of the fault type, and each time the caller finishes calling a function, it is necessary to check the error and handle it accordingly. This pattern is in contrast to the primitive error-handling of C, and there is no substantial improvement. In practical applications it is easy to form a multi-layered nested If Else statement, you can think of this coding scenario: first determine whether the file exists, if there is open file, if open successfully read the file, if read successfully write a piece of data, and finally close the file, do not forget to deal with each step of the error situation, How sick and Ugly is this code written? It is common practice to return early in order to avoid nesting of multi-layered curly braces, but the consequence of this is that many error-handling code is placed in front of the prominent position, while conventional processing logic is buried behind it. Also, the standard interface of an Error object can only return an error literal, and sometimes the caller needs to parse the text in order to distinguish between different types of errors. In addition, you can only manually cast the error type to a specific subtype. As for the panic-recover mechanism, the fatal flaw is not to cross the boundaries of the library to use, destined to be a semi-finished, at most only in their own pkg play a play. Java's exception handling also has its own problems (such as checked Exceptions), but overall it is much smarter than Go's error handling.
1.5 garbage collector (GC) is imperfect and has major flaws
On the eve of Go 1.0, its garbage collector has a memory leak in a 32-bit environment, and has been dragging and refusing to improve it, not to mention. The true fatal flaw of the Go language garbage collector is that it can cause unpredictable intermittent pauses throughout the process. Like some large background service programs, such as game servers, app containers, due to large memory, the number of memory objects, GC to complete a recovery cycle, may take a few seconds or longer, during this time, the entire service process is blocked, paused, in the external view is service interruption, no response, The more awesome concurrency mechanism is here to fail. The garbage collector starts on a regular basis and causes a short service outage every time it is started, does anyone else dare to use it? This is a background server process, which is the key application area of Go language. The above phenomenon is not my hypothesis, but the fact that the reality of the problem, by its serious distress is not a family of two (as of the beginning of 2014). In practice, you must try to reduce the number of objects in the process so that the intermittent pauses caused by GC can be controlled within an acceptable range. Besides, you have no choice (do you want to change the GC algorithm yourself, or even cut off the GC?). Is that still the go language? )。 Outside the circle, I have been thinking recently, must I need a garbage collector? Is it necessarily a throwback to history without a garbage collector? (You may write a new blog post topic discussion.) )
1.6 Disable unused variables and extra import
The go compiler does not allow the use of unused variables and unnecessary imports, which, if present, will inevitably result in compilation errors. But the reality is that in code writing, refactoring, debugging, for example, a temporary comment off a line of code, it can easily lead to the simultaneous use of unused variables and redundant import, direct compilation error, you have to appropriately comment out the variable definition, Page back to the file header to the extra import also commented out, ... When things are done, you want to get the code you just commented back, and then you have several troublesome steps. There is a problem with the egg, write the database-related code, if you import a database-driven pkg, it compiles to you error, said do not need to import this unused pkg; but if you listen to the compiler to delete the import, compile is passed, the runtime must error, Said the database driver could not be found; you see programmers are tossing on both sides is not people, finally have to ask out the great god _
. A better solution to this problem is to treat it as a compile warning rather than a compilation error. But the Go language developer is stubborn and does not tolerate this compromise.
1.7 How to create an object too much to be tangled
What do you choose to create an object by calling the new function, calling the Make function, calling the new method, and initializing the struct directly using the curly brace syntax? Bad choice, because there is no fixed pattern. In practice, if you want to create an object of a language built-in type (such as channel, map), usually created with the Make function, if you want to create a standard library or a third-party library-defined type of object, first go to the documentation to find out if there is a new method, if there is a better call to create the object, If there is no new method, the object is created with the initialization of the struct body, followed by a fallback. This process is quite a struggle, not like C + +, Java, C # as directly new on the line.
1.8 object does not have constructors and destructors
There is no constructor to say that, after all, there is a custom new method, which is generally considered a constructor. No destructor is more uncomfortable, can not achieve raii. Additional manual cleanup of resources has undoubtedly increased the programmer's mental burden. It's not human, but we programmers have less work overtime? There are destructors in C + +, although there is no destructor in Java but someone's home finally statement Ah, go, nothing. Yes, you have a defer, but that defer problem is bigger, see below.
The semantic setting of 1.9 defer statement is not very reasonable
Go language Design The starting point of the defer statement is good, the "code" that frees the resource is placed close to where the resource was created, but the "action" of releasing the resource is deferred (defer) until the function returns. Unfortunately, the timing of its implementation seems to be somewhat unreasonable. Imagine a function that needs to run for a long time, with an infinite loop of statements that constantly create resources (or allocate memory) in the loop body, and use defer statements to ensure that they are released. Since the function is running without return, all defer statements are not executed, and a large number of ephemeral resources created during the loop are accumulating and not being recycled. In addition, the system also needs additional resources in order to store the defer list, and it continues to increase. This way, after a while, the entire system will collapse due to resource exhaustion. Like this kind of long-running function, HTTP. Listenandserve () is a typical example. In the key applications of Go language, it can be said that almost every background service program must have such a class of functions, often also is the core of the program. If the programmer accidentally uses the defer statement in these functions, you can say endless. Wouldn't it be better if the language designer had set the semantics of defer to execute at the end of the owning code block, rather than when the function returned? But the Go 1.0 has already been released, and it's impossible to change it for backwards compatibility. Be careful with defer statements! Accidentally on the middle of the recruit.
1.10 Many language built-in facilities do not support user-defined types
Only language built-in types are supported for in, make, range, channel, map, and so on, and user-defined types (?) are not supported. A user-defined type cannot support a for-in loop, and a user cannot write a function like make, range, "parameter type and number" or even "return value type and number", and cannot write a data type like channel, map, which is like a generic type. The language built-in those things, everywhere is filled with highlighted by fascinating traces. This embodies the limitations, closeness, and imperfections of language design, such as the work of a novice--regardless of the authority of the designer and the person who implements it.
1.11 No generic support, common data type interface ugly
Without generics, the interfaces of the common basic data types of List, Set, and tree can only be ugly: the object being put in is a concrete type, taken out to be of an untyped type interface{}
(which can be considered the underlying type of all types), and forced to be used after the type conversion. The go language lacks functions such as Min and Max, and the function of calculating the absolute value of ABS only receives/returns a double-precision decimal type, and the sort interface can only be used with sort. interface helpless to avoid being compared to the type of object, and so on, are not the result of generic type results. Without generics, interfaces are hard to gracefully get. The go developer does not explicitly reject generics, but says it has not found a good way to implement generics (it is possible to learn a language that is already open-source). The reality is that Go 1.0 has been stereotyped, generics have not, those ugly interfaces must exist for a long time to keep backwards compatible.
1.12 Implementing interfaces does not require explicit declaration
This article is usually advertised as the advantage of Go language. But there are people who disagree, like me. If a type silently implements an interface in the go language, it is difficult for both the user and the maintainer to find it (unless you carefully check the function signature of each method of the type, and contrast it with all possible interface definitions), it is not natural to expect that the application associated with the interface is very cryptic and not intuitive. Supporters may argue that I can indicate what interfaces it implements in the documentation. The problem is that writing in a document is not as straightforward as writing to a type definition, but at least a static type check of the compiler is also available. Lack of compiler support, when the function signature of the interface type is changed, when the implementation of the interface type method is inadvertently changed, the implementation may be difficult to realize that the type implementation of the implicit constraints of the interface has actually been broken. It is also argued that I can make sure that the type is properly implemented through unit testing. What I want to say is that obviously can realize the interface through the explicit declaration, enjoy the compiler provides type check, you have to make trouble for yourself, to write the original extra unit test, find abuse is very cool? The go language approach, in addition to reducing some of the interface of the library dependencies, no other benefits, not worth the candle.
1.13 Omit parentheses but save curly braces
The IF statement inside the go language, whose conditional expression does not need to be expanded with parentheses, is advertised as evidence of "relatively concise code". However, you omit the parentheses, but you can not omit the curly braces Ah, a complete if statement at least three rows, people C, C + +, Java can be done in one line (can be omitted curly braces). People also have x?a:b
expressions, but also a line to do, you go to the language with if else write at least five elements it? Where's the simplicity?
1.14 compilation generated executable file size is very large
Remember that year I wrote a very simple program, the name and value of all the system environment variables output to the console, the core code is then 35 lines, the results compiled to scare me: exe file size of more than 4MB. If the C language is written in the same function of the program, 0.04MB are many. I fed this information back to the official community, and it turned out to be indifferent. Yes, I know now the hard drive capacity is hundreds of GB, up TB ... Can you optimize the degree of ... How to make me believe that you can do well in other places. (Again, all my experience and data comes from the eve of Go 1.0 release.) )
1.15 Dynamic load class library not supported
Statically compiled programs are certainly good, no additional runtime dependencies, and are easy to deploy. But as we said before, statically compiled files are very large in size. If a software system is made up of multiple executable programs, it adds up to a considerable amount. If you use dynamic compilation, you can save a lot of capacity when you publish with the same set of dynamic libraries. More crucially, dynamic libraries can be loaded and unloaded at run time, which is not available at the static library. There are also those third-party C libraries, such as LGPL, that are subject to copyright restrictions that do not allow static compilation. As for the version management challenges of dynamic libraries, you can resolve them by adding version numbers to all symbols in the dynamic library. In any case, the programmer should be given the option to decide whether to use a static library or a dynamic library. One-size-fits-all rejection of dynamic compilation is inappropriate.
1.16 Other
- Methods and function overloads are not supported (overload)
- Import of PKG Imports statement the back part is text (import "FMT")
- Without enum types, global constants are difficult to classify, and iota complicate simple things.
- When defining an object method, the receiver type should be either a pointer or a non-pointer.
- The syntax for defining structs and interfaces is slightly more complex,
interface XXX{}
struct YYY{}
isn't it more concise? The front plus type
keyword looks wordy.
- There is no assertequal function in the test class library testing, and the standard library is flooded with unit test code
if a != b { t.Fatal(...) }
.
- Language is too simple to give up a lot of useful features, "Keep the language simple" is often a reason to refuse to improve.
- The implementation of the standard library is generally not ideal, its code quality is probably in the "Basic available" degree, real to enterprise-level application areas, often exposed many shortcomings.
- Version has grown to 1.2, the Goroutine Scheduler still uses only one system thread by default. The long-term presence of gomaxprocs seems to imply that officials have never had enough confidence to allow the scheduler to operate safely and correctly in multicore environments. This is a fatal contradiction to the localization of the go language itself with the concurrency as its core.
The above list is what I can still think of the go language of the discomfort, after all, time over two years, and some have long been forgotten. Some of them are small uncomfortable, may endure a endure on the past, but a lot of bad accumulation up, always make people uncomfortable, time has a self-abuse feeling. The programmer's work life is already dull enough, why?
It must be said that, for most of the discomfort, I (Liigo) have tried to change them: Before the release of Go 1.0, I made a lot of comments and suggestions in their official mail group, to fight hard, can say that a great deal of effort, the purpose is to hope that the post-training go language is a relatively perfect, Programming languages with no apparent flaws. The result is disappointing, I poor weight not, weak, can not affect the whole language development trend. Before 1.0, the best way to deny yourself and surpass yourself is to miss it so sadly. I finally found that many times it was not a technical problem, but a technician's problem.
2nd: Why am I upset about some people in the go language?
The "certain people" mentioned here are mainly two types: first, Google employees who are responsible for the full-time development of the go language, and the advocates of the go language and the brain-stump fans. I've had a lot of dealings with these two kinds of people, patience. Again, I mean "some" people, not everyone, please do not.
Some members of Google's core development team, who specialize in developing the go language, tend to be open-ended, opinionated, and do not pay attention to recommendations made by third parties. They often say that the mantra is: the existing practice is very good, do not need that function, we develop the go language is for Google's own use, Google does not need that feature, if you must change the fork after you change, do not make comments please submit code. Many words and deeds are "anti-open source". Through some concrete examples, we can see this layer more visually. Just leave it as homework after class.
The last thing I can accept is their sloppy handling of the 1.0 release. At that time go not to 1.0, the fledgling pupils, there is a lot of room for improvement, is a comprehensive renovation of the best time, then do not change when? 1.0 is the version of the Foundation, the foundation is not reliable, and so on after 1.0 stereotypes, everywhere subject to backward compatibility, do anything tied feet, each step forward with resistance heavy. Eager to release 1.0, premature stereotypes, leaving many regrets, highlighting the developer's utilitarian, technically not the pursuit of perfection.
The core development members of Go language, their daily development work is using C language--go language compiler and runtime library, including language core data structure map, channel, Scheduler, all C developed-- There are few opportunities to actually develop real-world applications with the go language you develop, although the standard library is written by the go language, but they do not have the experience of using the standard library in a wide range. In fact, they lack the use of the go language of the actual development experience, often do not know what users in the forefront of the development of what really need to put yourself in the programmer's shoes. The lack of hands-on experience with the go language also means that they are not able to discover and improve the lack of go language in their daily development. That's why they tend to feel good about themselves.
Go language Community, there are a large number of go language advocates and brain-remnant fans, they are satisfied with the status quo, do not think enterprising, everywhere to maintain the heart of the "God", not to criticize the opinion, not support the language improvement requirements. When I had a lot of criticisms and improvements in the go language, and I rarely got their support, they didn't support the shock, and I wondered, did they want the go language to be more perfect and good? I later realized that they and amid's apple brain fans, words and deeds same strain, with extreme religious tendencies, deified masters, anti-dissidents really spared no effort. Simple technical problems can be raised to ideological battles. Real examples are quite a lot of, interested in the Internet to find it. It is because of their presence that more sane, sober, go language users are unable to truly integrate into the entire community.
If a project, a team, a community, filled with praise, narcissism, self-satisfaction, not thinking ahead, rejecting dissent, refusing to accept the new plan, I can't think of anything else that will drive me forward. Riding, it is not in the back.
3rd: Is there a better choice than the go language?
I have always adhered to a philosophical point of dialectic: that the best is available before a better alternative comes into being. Disappointment is useless, complaining is useless, either accept, or flee. I have tried to accept the go language, after failure, doomed to flee. The discovery of better alternatives has undoubtedly accelerated the escape process. Is there a better alternative to the go language? Of course. As a dick-wire programmer, I should tell you what it is, but I don't say. It's not the right time. I do not want to oppose these two programming languages now, triggering another potential language war. This is not the intention of this article. If you want to guess what it is from the information you have, it is entirely your own business. If you are willing to wait, it may soon surface, it is not known.
Section 4th: Written in the last
I do not want to be represented by others or to represent others. This article is written by me, a programmer named Liigo's Gen Y Stud, his own point of view. You can subjectively think that it is subjective, and can objectively assume that it is objective, anyway, that is your point of view.
The text was packed out of memory. Some of the details can be tested, but not worth the test. --I've fled, I don't want to go back to the scene. Some of the details involved may affect their accuracy due to some deviations, or they may affect their objectivity because of lack of provenance. If someone is serious, I have to check, I believe those things should still be there.
go language is not as useless as described above, it certainly has its advantages and characteristics. Readers judge a thing, should be the pros and cons and Chen, do comprehensive analysis, can not listen to my one negative words. But it's the bad stuff that always makes me uncomfortable and can't be completely neutralized from its excellent place, which is why I have to give it up.