Ready? Go! Previous: Boulevard to Jane (turn)

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

This article is divided into two parts in May 2012 and June of the "Programmer" magazine. At that time the go language had just launched the first stable version: Go 1. There was a slight deletion in the posting.


The go language is a statically compiled language that Google introduced in 2009, designed to provide developers with a python,ruby-like language environment, as well as the same operational efficiency as C + +. As an open source project, in the past two years, go in the form of community collaboration, continue to improve the language and standard library design and implementation. The first stable release was released on March 28 this year: Go version 1, go 1. The launch of Go 1 means that the go language and its standard library have entered a stable phase. For prudent developers, developing go programs is now a safe way to develop go programs without having to think about future changes in grammar and standard libraries.


As the go official says, the purpose of go 1 is to release a stable go language implementation, not a full-fledged change. So for developers who are already familiar with go, go 1 does not differ greatly from previous versions. Most of the modifications are the re-organization of the standard library namespaces. This series contains up to two articles, which focus on the development background of go, some syntax and type systems, and the next section discusses the concurrency model and toolchain for go.


All the code in this article can be found on GitHub.

Compile efficiency, operational efficiency, development efficiency

Once the code, the product read, as if the scholars are full of scripture, whispering softly, blowing piano chat. Not under the smoke, with the compiler to argue. ---Dick P. Gabriel


According to the Go Official FAQ, go appears to compensate for the shortcomings of other languages in system-level development. In this sentence, it is inevitable that some people will feel that the birth of go is just a few computer industry big guy---Go the original core developers include Robert Griesemer, Rob Pike, Ken Thompson---complaining about their own unscrupulous descendants, and in The Spit groove at the same time, Self-fencing developed such a language. But more to the point, I'm afraid they have seen and experienced Google's system-level development, summed up in a heterogeneous, distributed multi-core system on the way to survive. The problems Google faces today may be precisely the interview questions of every company in a few years. Go is not so much a castle in the castles as it is a slightly bitter development history after the big guy in the system development world enters a new era.


The basic design concept of GO is: compiling efficiency, running efficiency and development efficiency should be taken into account. With go development, developers can feel the convenience of Python, the efficiency of C/D + +, and the small-to-negligible compilation time. To achieve this concept, the following features of the Go language are formed:

    • Compiled, statically typed language. This allows for system-level applications that are sensitive to operational efficiency.

    • garbage collection, removing complex memory-freeing work.

    • Concise notation and syntax that strongly reduces the number of characters entered by the developer.

    • flat type system that removes complex inheritance relationships. The use of structured type systems (Structural type System) simplifies pre-design work and provides a non-intrusive solution for future additions to the abstraction layer.

    • based on the CSP model parallelism, the communication and data sharing between concurrent structures is simplified. Lay the groundwork for program development in the multicore era.

    • using a simple set of specifications, Developers no longer have to write scripts alone to specify dependencies and compile processes. By simply using the code itself and the Go tool chain, you can handle a variety of dependencies. After writing the code, a command, automatic down various dependencies, directly compiled/installed. No tools such as make,autoconf,automake,setup.py are supported.

The first two points should be self-explanatory. This series of articles focuses on a detailed analysis of the latter five points. The second half of this article discusses the syntax and type system, and the next section discusses the concurrency model and toolchain. There is no discussion about how to improve the efficiency of compilation, because of the details involved in more compiler implementations.


Simplify and simplify, grammar yourselves

public static <i, o> listenablefuture<o> chain (listenablefuture<i>input, function<? Super I,? exte NDS listenablefuture<? Extends O>>function) Oh, heaven! O Earth! Stop the goods now! ---from a chat record


Beginners go, will make people feel it in the spirit of C language, is not the strong behind the development team and their C language inextricably linked, not only go to the system-level development of the attention and its class C syntax. It is a simple and practical grammar that makes people striking memorable. In 21st century, a serious general-purpose programming language, using a language specification of only about 20,000 words, defined only 25 keywords and 42 operators, covering all aspects of concurrency, object-oriented, and so on, for developers, the language is too scary to be worth a try.


Here are some of the syntax:

  • There's no semicolon. In fact, in the Go Language specification, the statements in go are actually separated by semicolons. But the go language rules that the lexical analyzer automatically adds semicolons using a set of rules. This requirement for the word Analyzer brings up an encoding specification: the opening brace should not be written separately on one line, otherwise the lexical analyzer may produce unnecessary semicolons. This is a coding specification, but the result is that developers do not have to consider semicolons. Take the Go standard library, where there is no statement, requiring the developer to explicitly write down the semicolon.

  • Using the: = operator to declare a variable and its initial value, you do not have to explicitly indicate the variable type, because the initial value already illustrates the type of the variable. Imagine declaring a struct/class. Using Java requires foo.foo a = new Foo. Foo, while Go is just a: = new (foo. Foo). This can reduce a lot of typing for longer type names. One thing to note is that the = operator completes the operation of the variable declaration and assignment at the same time. If a variable has been declared before, just to assign it a value, the usual = assignment is still used.

  • For,if the judging conditions, and switch control statements without parentheses. In other words, if a < b {dosomething ()} can be written. You can also write Switch B {case 1:dosomething ()}.

  • All loops are only for one keyword. For the For loop there are several ways to do this: the C language for loop is similar to the notation for I: = 0; I < 10; i++ {dosomething ()}; and C language while loop similar notation for i < {dosomething ()}; and unconditional loop for {iteration ()}; In addition, for a slice type (similar to an array in Java, a Linear structure) and the map type (implementation of the hash table in Go), you can also work with the range keyword to traverse the stored member, such as for I, E: = Range list {dosomething (I, E)}.

  • Intuitive and simple access control. Only variables, functions/methods, or structures whose names begin with a capital letter can be accessed by the package outside code. Otherwise it is only visible within the package. This not only simplifies access control, but also allows the developer to know the access criteria by simply seeing the name and not having to look for a declaration.

  • The condition of switch can be an expression and can have no control statement. This means that the following statements are valid:

Switch {

case I% 2 = = 0:

Process_even (i)

Case I% 2! = 0:

Process_odd (i)

}

These seemingly casual changes, but effectively simplifies the writing and reading of the program. Allowing developers to reduce typing makes it easier to read programs. Since these changes and features are not complex, this is not an introduction.


Orthogonal principles: Data, methods, reuse, and abstraction

I know [C + +] so [complex], if we can go back, we will certainly engage in an object-oriented version of C language out. ---Ken Thompson,unix founder, go language author, in an interview about go and object-oriented.


This section mainly discusses the type system of go. Like the C language, go also uses structs for data abstraction:

Type Duck struct {

Name string

}

Next, you can define a method for this structure:

Func (d *duck) Eat () {

Fmt. Println (D.name,

"Duck is has dinner!")

}

Unlike the C++,java class, adding a method to a struct does not have to declare the method when declaring the struct. Just make sure that the method is defined in the same package as the struct. This separates the data from the behavior, and in the design data abstraction (struct) phase, no specific behavior is considered. The (d *duck) Following the Func keyword indicates which type this method belongs to. d This variable is a "receiver", in the definition of the method, D is used similar to the this pointer in C++/java.


Then we can use this struct and its methods:

Func Main () {

D: = new (Duck)

D.name = "Donald"

D.eat ()

}

According to the law of object-oriented language, the next step should introduce the inheritance mechanism. The answer to go is simple: no inheritance. This may sound unreasonable, but it brings immediate benefits: it greatly simplifies the type system. On the one hand, compilers can be more efficient; On the other hand, developers do not have to consider a variety of complex inheritance relationships beforehand.


However, the benefits of inheritance are also obvious: first, reuse, subclasses can directly inherit the implementation of the method of the parent class, reduce duplication of code, second, polymorphic, the developer can use a more abstract representation (the parent class) to invoke the specific implementation (subclass), so you can write common code at the level of abstraction to operate.

It is obviously unwise for go to simply remove the inheritance mechanism and not face the problems that the succession has to solve. To do this, go uses two sets of mechanisms to achieve the effect of inheritance: Anonymous members implement code reuse, interface types implement type abstraction.


To implement code reuse, go has introduced the concept of "anonymous member" (Anonymous Field) in the structure definition. Learn about object-oriented design developers must have heard that the principle of code reuse should be prioritized using object combinations rather than inheritance. The anonymous member of Go is actually a combination of objects.

Continuing with the above example, if you need to define a donaldduck type, its Eat method implementation is the same as duck, but with a member named Age:

Type DonaldDuck struct {

Duck

Age int

}

As you can see, simply place the name of the duck type in the definition of the struct. Since the name of the member is not shown, it is named "Anonymous member". This notation essentially defines a different struct, which contains a type of duck, and the name is also called the Duck member (yes, the member name and the type name are the same). At the same time, it also contains a member of type integer, named age.


So what does this anonymous member really mean for code reuse? Go has a special rule for anonymous members: structs that contain anonymous members also have methods for anonymous member types. Simply put, for the above example, DonaldDuck contains anonymous member duck, then it is as if DonaldDuck implements the duck of the various methods. In this way, the following code is easy to understand:

Func Main () {

D: = new (DonaldDuck)

D.name = "Donald"

D.age = 10

D.eat ()

}

We first need to apply for an object of type DonaldDuck, then assign values to each member of the object, and finally call the Eat () method. So far, we've seen that using anonymous members enables code reuse like inheritance. But it's a little bit less than inheritance. For example, you cannot assign an object address of type DonaldDuck to a pointer of type duck. You also cannot redefine the implementation of the Eat method in DonaldDuck. Simply put, anonymous members simply make some simplification at the grammatical level and do not touch the content of any type of system. For a type system, DonaldDuck and Duck are completely two different types.


To implement another part of the inheritance mechanism, namely polymorphism, go introduces the concept of the interface type. Like interfaces in Java, Go's interface is also a prototype of a set of methods, followed by a concrete structure (class) method to implement various interfaces. But unlike Java, go uses a structured type system like OCaml (Structural type System), which does not require that the type of the interface be implemented to declare exactly which interfaces to implement. Just define all the methods that are consistent with the interface type, saying that the type implements this interface. Specifically, for the above code, we can define a animal interface:

Type Animal Interface {

Eat ()

}

Only one method is defined in this interface: Eat, which has no input parameters and no return value. So far, both duck and DonaldDuck are implementations of the animal interface. Yes, you do not have to modify the code for Duck and DonaldDuck, you do not have to show the implements Animal, as long as the Eat method is implemented, and the prototype is consistent with the definition of the interface type. Then we can simply declare a pointer of type Duck and assign it to a variable of the animal interface type:

Func Main () {

var a Animal

D: = new (Duck)

D.name = "Don"

A = d

A.eat ()

}


If you also want to implement animal this interface, you only need to implement the Eat method for these types.


This type of interface provides developers with a convenient "first implementation, post-abstraction" mechanism. Because the interface itself is non-intrusive, it is not necessary to explicitly specify which interfaces to implement when defining the structure. Developers can define an interface type after implementing some structure and then looking for a common interface representation between them. At this time, any implementation of the interface of the specified method of the type, is already the implementation of this interface. There is no need to modify previously well-run code, and it greatly simplifies the development process. Imagine that in tens of thousands of lines of code, looking for several types of implementations of certain methods, even if only two words are added to the definition of each type, it is enough to make life boring.


This "first realization, post-abstraction" mechanism also conforms to the general law of our understanding of the world. Even the code that you write is often used for a period of time to discover some of the abstract representations behind them. Simply requiring a well-defined level of type at the design stage prior to code development is a ridiculous way of ignoring the limitations of human understanding. Go, as a practical language, admits this limitation while providing people with a plan to minimize the cost of modification.


The Go type system embodies another design principle for go: the orthogonal principle. In linear algebra, orthogonality means that none of the vectors can be projected onto other vectors. Extension to the field of programming, is that any feature is only for one problem, and there is no intersection between each other. Specific to the go type system, it is reflected in the separation of methods and data, and the separation of reuse and abstraction. This separation allows developers to effectively select different features for the problem by analyzing the problem itself.


Summary

This article focuses on the grammar and type system of the go language. Some basic design principles of go are emphasized. All of this is based on brevity, trying to cover a variety of common problems with minimal language features, which resembles the C language of the year. Although such a design may not usher in much academic acclaim, it is enough to save developers from complex grammatical design, layers of type relationships, and to solve problems at hand in a clearer and simpler way.

But only these are not enough to make go continue to write the C language brilliant. It must confront the problems that it must face in its time, and that is the challenge of multicore. Today's programs can no longer be expected to increase efficiency on a single core, but to improve the effectiveness of the entire process. In the multi-core era, developers have to explore potential parallel structures in the program to maximize the use of multi-core parallel capabilities. And go provides developers with the tools to handle the new challenges of multicore. In the next issue we will focus on the processing of the parallel structure in the go language, and the Go tool chain. Please pay attention.


--------------------------------------------------------------------------------------

Welcome to pay attention to code surgery!



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.