ArticleDirectory
- Variable Declaration
- Condition Statement
- Branch statement
- Loop
- Function
- Basic Type
- Struct type
- Method
- Interface
- Inheritance
- Go routine
- Channel Type
What is the go language?
Google recently released a newProgramming Language, Go. It is designed to bring the advanced nature of modern programming languages to the system level that is still dominated by C language. However, this language is still being tested and evolving.
Designers of the Go Language Plan to design a simple, efficient, secure, and concurrent language. This language is so simple that there is no need for a symbol table for lexical analysis. It can be compiled quickly. The compilation time of the entire project is usually less than seconds. It has the garbage collection function, because the memory is safe. It performs static type check and does not allow forced type conversion. Therefore, it is safe for types. At the same time, the language also has a powerful concurrency implementation mechanism.
Read go
The Go syntax inherits the same style as C.ProgramIt is composed of functions, and the function body is a series of statement sequences. SectionCodeThe block is enclosed in curly brackets. This language retains limited keywords. The expression uses the same infix operator. The syntax is not surprising.
When designing this language, the author of The go language adheres to a single guiding principle: simplicity, clarity, and supremacy. Some new syntax components provide a concise way to express some conventional concepts. In contrast, the expression in C is lengthy. In other aspects, we have made improvements to some unreasonable language choices that have been presented during decades of use.
Variable Declaration
The variables are declared as follows:
VaR sum int // simple declaration var total Int = 42 // declare and initialize
It is worth noting that the types in these declarations followBack. It seems strange at first glance, but it is clearer. For example, for the c segment below:
Int * a, B;
It is clear, but here it actually means that A is a pointer, But B is not. To declare both of them as pointers, you must repeat the asterisks. In the go language, you can declare both of them as pointers in the following way:
VaR A, B * int
If a variable is initialized, the compiler can generally infer its type, so the programmer does not need to explicitly knock it out:
VaR label = "name"
However, in this case, VaR is almost redundant. Therefore, the author of Go introduces a new operator to declare and initialize a new variable:
Name: = "Samuel"
Condition Statement
The condition clauses in the go language are the same as the IF-else structures in C, but they do not need to be packaged in parentheses. This reduces visual confusion when reading code.
Parentheses are not the only removed visual interference. A simple statement can be included between conditions, so the following code:
Result: = somefunc ();
If result> 0 {
/* Do something */
} Else {
/* Handle error */
}
Can be reduced:
If result: = somefunc (); Result> 0 {
/* Do something */
} Else {
/* Handle error */
}
However, in the following example, the result is only in the condition block.InternalValid -- in the former, it is accessible throughout the context that contains it.
Branch statement
Branch statements are also familiar, but they are also enhanced. Like a conditional statement, it allows a simple statement to be placed before the branch expression. However, they go further than the branches in the C language.
First, two modifications were made to make the branch jump more concise. This can be a list separated by commas, and fall-Throuth is no longer the default action.
Therefore, the following C code:
Int result;
Switch (byte ){
Case 'A ':
Case 'B ':
{
Result = 1
Break
}
Default:
Result = 0
}
In go, it becomes like this:
VaR result int
Switch byte {
Case 'A', 'B ':
Result = 1
Default:
Result = 0
}
Second, the Go branch jump can match more content than integers and characters. Any valid expression can be used as the jump statement value. As long as it is of the same type as the branch condition.
So the following C code:
Int result = calculate ();
If (result <0 ){
/* Negative */
} Else if (result> 0 ){
/* Positive */
} Else {
/* Zero */
}
It can be expressed in go as follows:
Switch result: = calculate (); true {
Case result <0:
/* Negative */
Case result> 0:
/* Positive */
Default:
/* Zero */
}
These are common conventions. For example, if the branch value is omitted, it is true by default, so the above Code can be written as follows:
Switch result: = calculate ();{
Case result <0:
/* Negative */
Case result> 0:
/* Positive */
Default:
/* Zero */
}
Loop
Go has only one keyword for introducing loops. However, it provides all the available cycle methods in C language except do-while.
Condition
For A> B {/*...*/}
Initial, condition, and step
For I: = 0; I <10; I ++ {/*...*/}
Range
The expression on the right of the range statement must be array, slice, string or map, or a pointer to array or channel.
For I: = range "hello "{/*...*/}
Infinite Loop
For {/* ever */}
Function
The syntax for declaring a function is different from that for C. Just like a variable declaration, types are declared after the terms they describe. In C:
Int add (int A, B) {return a + B}
In go, it is described as follows:
Func add (a, B INT) int {return a + B}
Multiple return values
A common practice in C is to retain a returned value to indicate an error (for example, read () returns 0), or retain the returned value to notify the status, and the pointer to the memory address that passes the stored results. This is prone to insecure programming practices, so it is not feasible in a well-managed language like the Go language.
Recognizing that the impact of this problem is beyond the scope of simple requirements for function results and error communication, the authors of go have built in the language the ability of functions to return multiple values.
As an example, this function returns two parts of Integer Division:
Func divide (a, B INT) (INT, INT ){
Quotient: = A/B
Remainder: = A % B
Return quotient, remainder
}
With multiple return values, it is better to have a good code document-and go allows you to name the return values, just like a parameter. You can assign values to these returned variables, just like other variables. So we can rewrite divide:
Func divide (a, B INT) (quotient, remainder INT ){
Quotient = A/B
Remainder = A % B
Return
}
The appearance of multiple return values promotes the "comma-OK" mode. A function that may fail can return the second boolean result to indicate success. As an alternative, you can also return an error object, so the code like the following is not strange:
If result, OK: = moremagic (); OK {
/* Do something with result */
}
Anonymous Functions
With the Garbage Collector, it means opening the door to many different features-including anonymous functions. Go provides simple syntax for declaring anonymous functions. Like many dynamic languages, these functions create lexical closures within the scope they are defined.
Consider the following program:
Func makeadder (x INT) (func (INT) int ){
Return func (y int) int {return x + y}
}
Func main (){
Add5: = makeadder (5)
Add36: = makeadder (36)
FMT. println ("the answer:", add5 (add36 (1) // => the answer: 42
}
Basic Type
Like the C language, go provides a series of basic types, common Boolean, integer, and floating point types. It has a unicode string type and an array type. The language also introduces two new types: Slice and map.
Array and slice
Arrays in the go language are not dynamic as in the C language. Their size is part of the type, which is determined during compilation. The array index still uses the familiar C syntax (such as a [I]), and, like C, the index starts from 0. The compiler provides built-in functions to obtain the length of an array (such as Len (A) during compilation )). If you try to write data beyond the array limit, a runtime error is generated.
Go also provides slices as an array deformation. A slice is a continuous segment in a Number Group. It allows programmers to specify a specific part of the underlying storage. The syntax for constructing a slice is similar to accessing an array element:
/* Construct a slice on ary that starts at S and is Len elements long */
S1: = ary [s: Len]
/* Omit the length to create a slice to the end of ary */
S2: = ary [s:]
/* Slices behave just like arrays */
S [0] = ary [s] // => true
// Changing the value in a slice changes it in the array
Ary [s] = 1
S [0] = 42
Ary [s] = 42 // => true
The array segment referenced by this slice can be changed by assigning the new slice to the same variable:
/* Move the start of the slice forward by one, but do not move the end */
S2 = S2 [1:]
/* Slices can only move forward */
S2 = S2 [-1:] // This is a compile Error
The length of the slice can be changed as long as it does not exceed the length of the sliceCapacity. The size of the slice S is the size from S [0] to the end of the array, which is returned by the built-in cap () function. The length of a slice can never exceed its capacity.
Here is an example of interaction between length and capacity:
A: = [...] int {1, 2, 3, 4, 5} // The... means "whatever length the initializer has"
Len (a) // => 5
/* Slice from the middle */
S: = A [2: 4] // => [3 4]
Len (s), Cap (s) // => 2, 3
/* Grow the slice */
S = s [0: 3] // => [3 4 5]
Len (s), Cap (s) // => 3, 3
/* Cannot grow it past its capacity */
S = s [0: 4] // This is a compile Error
Generally, a slice is all required by a program. In this case, the programmer does not need an array at all. Go has two ways to directly create a slice without referencing the underlying storage:
/* Literal */
S1: = [] int {1, 2, 3, 4, 5}
/* Empty (all zero values )*/
S2: = make ([] int, 10) // cap (S2) = Len (S2) = 10
Map type
Almost all popular dynamic languages have data types, but what is not available in C is dictionary. Go provides a basic dictionary type called map. The following example shows how to create and use go map:
M: = make (Map [String] INT) // a mapping of strings to ints
/* Store some values */
M ["foo"] = 42
M ["bar"] = 30
/* Read, and exit program with a runtime error if key is not present .*/
X: = m ["foo"]
/* Read, with comma-OK check; OK will be false if key was not present .*/
X, OK: = m ["bar"]
/* Check for presence of key, _ means "I don't care about this value ."*/
_, OK: = m ["Baz"] // OK = false
/* Assign zero as a valid value */
M ["foo"] = 0;
_, OK: = m ["foo"] // OK = true
/* Delete a key */
M ["bar"] = 0, false
_, OK: = m ["bar"] // OK = false
Object-oriented
The Go language supports an object-oriented style similar to that used in C. Data is organized into structs and then defined to operate these structs functions. Similar to Python, The go language provides a way to define functions and call them, so the syntax is not clumsy.
Struct type
Defining a new struct type is simple:
Type Point struct {
X, Y float64
}
Currently, this type of value can be allocated through the built-in function new, which returns a pointer pointing to a memory unit, and the memory slot occupied is initialized to zero.
VaR p * point = new (point)
P. x = 3
P. Y = 4
This is lengthy, and one goal of the Go language is to be as concise as possible. Therefore, a syntax for allocating and initializing struct at the same time is provided:
VaR P1 point = point {3, 4} // Value
VaR P2 * point = & point {3, 4} // pointer
Method
Once the type is declared, You can explicitly declare the function as the first parameter:
Func (self point) length () float {
Return math. SQRT (self. x * Self. x + self. y * Self. y );
}
These functions can then be called as struct methods:
P: = point {3, 4}
D: = P. Length () // => 5
The method can be declared as either a value or a pointer type. Go will properly process the referenced or unreferenced objects, so you can either declare the type new "> T or type * t and use them reasonably.
Let's extend a converter for point:
/* Note the specified er is * point */
Func (Self * point) Scale (factor float64 ){
Self. x = self. x * factor
Self. Y = self. y * factor
}
Then we can call it like this:
P. Scale (2 );
D = P. Length () // => 10
It is very important to understand the new "> Self passed to movetoxy is the same as other parameters, and isValueTransfer, rather than transfer by reference. If it is declared as a point, the modified struct in the method is no longer the same as that of the caller-the values are copied when they are passed to the method and discarded after the call ends.
Interface
Dynamic languages such as Ruby emphasize the object-oriented programming style and think that the behavior ratio of objects is dynamic.(Duck typing) is more important. One of the most powerful features of Go is that it provides the idea of using dynamic types during programming and pushes the work of checking the legitimacy of behavior definitions to compilation. The name of this behavior is calledInterface.
Defining an interface is simple:
Type writer interface {
Write (P [] Byte) (N int, err OS. Error)
}
An interface and a write byte buffer method are defined here. Any object that implements this method also implements this interface. The compiler can infer that it does not need to be declared Like java. This not only gives the ability to express dynamic types, but also retains the security of static type checks.
The operation method of interfaces in go allows developers to discover program types when writing programs. If several objects have public behaviors and developers want to abstract such behaviors, they can create an interface and use it.
Consider the following code:
// Somewhere in some code:
Type widget struct {}
Func (widget) frob () {/* Do something */}
// Somewhere else in the Code:
Type sprocket struct {}
Func (sprocket) frob () {/* Do something else */}
/* New code, and we want to take both widgets and sprockets and frob them */
Type frobber interface {
Frob ()
}
Func frobtastic (F frobber) {f. frob ()}
It is important to note that all objects implement this empty interface:
Interface {}
Inheritance
The Go language does not support inheritance, at least different from the inheritance of most languages. There is no type hierarchy. Compared with inheritance, go encourages combination and delegation, and provides corresponding syntax desserts to make it more acceptable.
With this definition:
Type Engine interface {
Start ()
Stop ()
}
Type car struct {
Engine
}
So I can write it like below:
Func gotoworkin (C car ){
/* Get in car */
C. Start ();
/* Drive to work */
C. Stop ();
/* Get out of car */
}
When I declare the struct car, I defineAnonymous Member. This is a member that can only be recognized by its type. Anonymous members have the same name and type as other members. Therefore, I can also write C. Engine. Start (). If the car does not have its own method to meet the call requirements, the compiler automatically delegates the call on the car to its engine.
The rule for the separation method provided by anonymous members is conservative. If you define a method for a type, use it. If not, use the method defined for anonymous members. If two anonymous members provide a method, the compiler reports an error, but only when the method is called.
This combination usesDelegateInstead of inheritance. Once an anonymous member's method is called, the control flow is delegated to the method. So you cannot simulate the type hierarchy like the following example:
Type Base struct {}
Func (base) magic () {FMT. Print ("base magic ")}
Func (Self base) moremagic (){
Self. Magic ()
Self. Magic ()
}
Type Foo struct {
Base
}
Func (FOO) magic () {FMT. Print ("foo magic ")}
When you create a foo object, it will affect the two methods of New "> base. However, when you call moremagic, you will not get the expected results:
F: = new (FOO)
F. Magic () // => Foo magic
F. moremagic () // => base magic
Concurrency
The authors of Go chose the message passing model as the recommended concurrent programming method. The language also supports shared memory, and the author makes sense:
Do not use shared memory to communicate. Instead, use communication to share memory.
The language provides two basic components to support this model: goroutines and channels.
Go routine
Goroutine is a lightweight parallel program execution path, similar to a thread, coroutine, or process. However, they are quite different from each other, so the go author decides to give it a new name and give up the meaning that other terms may imply.
It is very easy to create a goroutine to run the function named dothis:
Go dothis () // but do not wait for it to complete
Anonymous functions can be used as follows:
Go func (){
For {/* Do Something forever */}
} () // Note that the function must be invoked
These goroutine maps to appropriate operating system primitives (such as POSIX Threads) through go runtime ).
Channel Type
With goroutine, it is easy to execute code in parallel. However, communication mechanisms are still required between them. Channel provides a FIFO communication queue to achieve this goal.
The channel syntax is as follows:
/* Creating a channel uses make (), not new-it was also used for map creation */
Ch: = make (Chan INT)
/* Sending a value blocks until the value is read */
Ch <-4
/* Reading a value blocks until a value is available */
I: = <-CH
For example, if we want to perform a long-running numerical calculation, we can do this:
Ch: = make (Chan INT)
Go func (){
Result: = 0
For I: = 0; I <100000000; I ++ {
Result = Result + I
}
Ch <-Result
}()
/* Do something for a while */
Sum: = <-ch // This will block if the calculation is not done yet
FMT. println ("the sum is:", sum)
Channel blocking is not always the best. The language provides two customization methods:
- The programmer can specify the buffer size-messages sent by the channel to be buffered will not be blocked, unless the buffer is full and reading from the buffered channel will not be blocked, unless the buffer is empty.
- The language also provides the ability to send and receive messages that are not blocked, and the operation is successful but still needs to be reported.
/* Create a channel with buffer size 5 */
Ch: = make (Chan int, 5)
/* Send without blocking, OK will be true if value was buffered */
OK: = CH <-42
/* Read without blocking, OK will be true if a value was read */
Val, OK: = <-CH
Package
Go provides a simple mechanism to organize code: packages. Each file starts with a declaration of which package it belongs to. Each file can also introduce the package it uses. The upper-case names of any letter are exported from the package and can be used by other packages.
The following is a complete source file:
Package Geometry
Import "math"
/* Point is capitalized, so it is visible outside the package .*/
Type Point struct {
/* The fields are not capitalized, so they are not visible
Outside of the package */
X, Y float64
}
/* These functions are visible outside of the package */
Func (self point) length () float64 {
/* This uses a function in the math package */
Return math. SQRT (self. x * Self. x + self. y * Self. Y)
}
Func (Self * point) Scale (factor float64 ){
Self. setx (self. x * factor)
Self. sety (self. y * factor)
}
/* These functions are not visible outside of the package, but can be
Used inside the package */
Func (Self * point) setx (x float64) {self. x = x}
Func (Self * point) sety (Y float64) {self. Y = y}
Missing
The author of the Go language tries to make the code clear and clear as the guiding ideology for designing all decisions of the language. The second goal is to produce a language with a high Compilation speed. With these two standards as the direction, it is not suitable for many features from other languages. Many programmers will find that their favorite language features do not exist in go. Indeed, many may think that the go language is not quite available due to its lack of some features common to other languages.
The two missing features are exception and generics, which are very useful in other languages. Currently, they are not part of go. However, because the language is still in the experimental stage, they may eventually be added to the language. However, if we compare go with other languages, we should remember that go is intended to be replaced by C language at the system programming level. If this is clearly stated, the many missing features are not a big problem.
Finally, this language has just been released, so it does not have any class libraries or tools to use, nor does it have an integrated programming environment for go language. The Go language standard library has some useful code, but this is still rare compared with more mature languages.
View Original English text: Google go: A primer.