Go (programming language)
Go | |
---|---|
Basic data | |
Paradigms : | concurrent , imperative , structured , modular , object-oriented |
Publishing year: | 2009; first stable version 2012 |
Designer: | Rob Pike , Ken Thompson , Robert Griesemer |
Developer: | Robert Griesemer , Rob Pike , Ken Thompson and others a. |
Current version | 1.15 (August 11, 2020) |
Typing : | strong , static |
Important implementations : | Gc, gccgo |
Influenced by: | C , Newsqueak , Alef , Limbo , Oberon |
Operating system : | Linux , macOS , FreeBSD , Windows , Experimental: DragonFly BSD , Plan 9 , Solaris |
License : | BSD license |
golang.org |
Go is a compilable programming language that supports concurrency and has automatic garbage collection . Go was developed by employees of Google Inc. The designs come from Robert Griesemer , Rob Pike and Ken Thompson .
overview
Go was developed out of dissatisfaction with the existing languages for software development such as C ++ or Java in the context of today's computer systems, especially with regard to scalable network services , cluster and cloud computing . Compared to C ++, Go has far fewer keywords. One of the problems Go wants to solve is compiler inefficiency in C and C ++. Important goals in the development were, among other things, the support of concurrency with native language elements and the facilitation of software development with large development teams and large code bases. Go has its own garbage collector , allows the use of pointers , but dispenses with pointer arithmetic . Go is a compiled language with a focus on high translation speed.
Go is syntactically based on the programming language C with some influence from the Wirth language family ( Pascal , Modula and especially Oberon ). The support for concurrency was modeled on the Communicating Sequential Processes (CSP) introduced by Tony Hoare and is in the tradition of the programming languages Newsqueak , Alef and Limbo .
Features and language resources
Go offers closures and reflection, as well as type safety and automatic garbage collection. Go supports object orientation through interfaces and mixins . In classes and inheritance of classes is deliberately avoided. It is also possible to modularize the source code using packages as with Java .
Concurrency is Communicating Sequential Processes realized that Goroutinen be called and via channels (Channels) can communicate. There are no generic types , but later integration cannot be ruled out.
Unicode is supported in the form of UTF-8 , both for strings and for variable identifiers in the source text (but only Unicode letters and numbers), Δt = t1 - t2
so it is possible.
syntax
The syntax of Go is essentially based on the syntax of the C programming language , but differs from it in some places. For example, statements do not need to be terminated with a semicolon. In declarations, data types are written after the identifier instead of in front of it in order to simplify the declaration of function types . Code blocks are separated with curly braces. In addition to the simple equal sign as an assignment operator, there is also an operator :=
that combines declaration with type inference and assignment. The language includes 25 keywords fewer keywords as ANSI C .
Comments are marked with slashes as in C or C ++; /*
to */
denotes a comment area , which can also contain several lines, introduces //
a comment area up to the end of the line.
Each source file belongs to exactly one package, which is package
specified at the beginning of the file with the instruction.
The key word for functions is func
that the function main
in the “main” package is the starting point of the Go program.
Each variable has a defined type.
Simple examples
package main
import "fmt"
func main() {
fmt.Println("Hallo Welt")
}
The above source text outputs the string on the output medium Hallo Welt
.
Another example calculates the circle number Pi approximately using the Leibniz series . Parallel Go routines and a channel are used for the calculation:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(calcpi(5000))
}
// calcpi startet n Goroutinen, um eine
// Näherung von Pi zu berechnen.
func calcpi(n int) float64 {
ch := make(chan float64, n)
for k := 0; k < n; k++ {
// alle n Werte parallel berechnen
go calcsubterm(ch, float64(k))
}
// das Ergebnis mit Null initialisieren
f := float64(0.0)
for k := 0; k < n; k++ {
// alle n Werte addieren
f += <- ch
}
return f
}
func calcsubterm(ch chan <- float64, k float64) {
ch <- 4 * math.Pow(-1, k) / (2*k + 1)
}
The individual summands of the mathematical series are executed in parallel and each write their results in the channel ch
. At the same time, the values from the channel are added to an overall result. The sequence of digits appears on the output device 3.141392653591793
. The deviation from the actual circle number from the fourth decimal place is mainly due to the slow convergence of the Leibniz series .
Type conversion
In contrast to the C language, types must always be converted. For example, it is not possible to store a value of the type integer in a variable of the type float without first converting the value. In the following example, a variable of the type Integer is declared and the value of this variable is assigned to another variable of the type Float. Note that a distinction is made between “int” and “uint”. "Unsigned Integer" "uint8" cover a range from (0 ... 255) while "int8" cover a range from (−128 ... 127). This procedure of strict typing is very useful because programming errors that are difficult to find can be identified more easily.
var int_variable1 int = 100
var float_variable1 float64 = float64(int_variable1)
var int_variable2 uint = uint(float_variable1)
If a value is assigned directly in the declaration, the explicit naming of the type is optional. The compiler determines this based on the value or the specified type converter functions. At the package level, each instruction must begin with a keyword, which is why the following short form can only be used within functions:
int_variable1 := 100
float_variable1 := float64(int_variable1)
int_variable2 := uint(float_variable1)
pointer
In contrast to many high-level languages such as Java, the GO programming language works with pointers. A pointer ( English pointer) whose value is the address of a storage area . Certain tasks cannot be programmed without a pointer. This includes the transfer of values to functions (call by reference). In the following example, a variable of the type “Integer” with the name “number” and the value 100 is initialized. Then the memory address, i.e. the address in the computer memory, is output. The address of the variable “number” is called up with “& number”. The pointer syntax is very reminiscent of the C language.
var nummer int = 100
fmt.Printf("Die Adresse der Variable: %x\n", &nummer)
In the next example, a variable of the type “Integer” with the name “number” and the value 100 is initialized. Then a pointer variable of the type integer pointer is declared. The type of a pointer variable is declared by a leading asterisk (*) in front of the variable type. “Int” becomes “* int”. Then the memory address of the variable “number” is declared as the value of the pointer variable “integer_pointer”. The address of the memory which was occupied by the variable “number” is then output. Finally, the value that is in the memory address is output. The value of a memory location that is declared in the pointer variable “integer_pointer” can be determined with “* integer_pointer”.
var nummer int = 100
var integer_pointer *int
integer_pointer = &nummer
fmt.Printf("Adresse gespeichert in der integer_pointer Variable: %x\n", integer_pointer) /* gibt eine Speicheradresse aus z.B. 10888000 */
fmt.Printf("Wert der Speicheradresse gespeichert in integer_pointer : %d\n", *integer_pointer) /* Gibt den Wert an welcher in der Speicheradresse steht */
A pointer address without a stored pointer is called a "nil pointer". You can simply query whether a pointer address has a memory address as its content or not.
if(integer_pointer != nil) /* Wenn zutreffend Zeiger Variable speichert einen Zeiger auf einen Speicherbereich */
if(integer_pointer == nil) /* Wenn zutreffend Zeiger Variable speichert keinen Zeiger auf einen Speicherbereich */
The last example shows the usage when calling a function. First, two variables of the "Integer" type are declared. The content of these two variables should be swapped.
var nummer1 int = 10
var nummer2 int = 50
// Anzeige vor dem Tausch
fmt.Printf("Wert der Variable nummer1: %x\n", nummer1)
fmt.Printf("Wert der Variable nummer2: %x\n", nummer2)
// Aufruf der Funktion tauschen
tauschen(&nummer1,&nummer2)
// Anzeige des Tausches
fmt.Printf("Wert der Variable nummer1: %x\n", nummer1)
fmt.Printf("Wert der Variable nummer2: %x\n", nummer2)
//Funktion tauschen
func tauschen(nummer1_pointer *int, nummer2_pointer *int) {
var zwischenspeicher int
zwischenspeicher = *nummer1_pointer
*nummer1_pointer = *nummer2_pointer
*nummer2_pointer = zwischenspeicher
}
You can roughly summarize that "&" determines the memory address of a variable, while "*" determines the stored value of a memory address.
Object orientation
Go supports object-oriented programming, but it is not class-based . Data types can have methods in Go . Polymorphism is interfaces ( interfaces reached), are linked via the method calls at run time to the specific implementation ( Dynamic binding ). A data type does not have to be explicitly declared that it fulfills a specific interface. Instead, this relationship is determined implicitly at compile time in order to achieve loose coupling .
Instead of inheritance and type hierarchies, Go uses composition. For this purpose, Go supports a form of mix-ins, which in Go is called embedding : a data structure can embed any number of other data types so that it contains their methods and data fields.
Example of types, interfaces and mixins:
package main
import "fmt"
// Definieren zweier Typen
type User struct {
Name string
}
type Admin struct {
User // Admin bettet zudem den Typ 'User' ein
Email string
}
// Ein Interface mit der Methode 'Notify()'
type Notifier interface {
Notify()
}
// User und Admin implementieren das Interface 'Notifier'
// Eine vorherige Deklaration zur Implementierung ist nicht notwendig
func (u User) Notify() {
fmt.Printf("User : Sending User Email To %s\n",
u.Name)
}
func (a Admin) Notify() {
fmt.Printf("Admin: Sending Admin Email To %s. His address is \"%s\".\n",
a.Name, // Verwenden des eingebetteten Feldes 'Name' vom User
a.Email)
}
func main() {
// Einen User und einen Admin erstellen
user := User{
Name: "john smith",
}
admin := Admin{
User: user,
Email: "[email protected]",
}
// Die implementierte Notify-Methode aufrufen
// Mittels dynamischer Bindung wird die Methode am richtigen Typ aufgerufen
user.Notify()
admin.Notify()
}
Concurrency
To support concurrent programming in Go, the concept of channels (channels) used, which provides a relatively highly abstract possibility of synchronous or asynchronous communication between Go routines. A channel is a memory area that is secured by semaphores and provides a queue (buffered / asynchronous channel) or just an interface (unbuffered / synchronous channel). Only data of a fixed type can be transmitted over a channel. However, there is no limit to the type, channels for channels are also conceivable.
A channel is created through the call make(chan typ)
(synchronous) or make(chan typ, größe)
(asynchronous, if size > 0). Then go routines can write to the channel, read from it and close it.
In the case of synchronous channels, read access blocks until another Go routine writes to the channel, or write access blocks until another routine reads. With asynchronous channels, this behavior only occurs if the channel to be read is empty or the channel to be written is full. In Go, there is no limit to the number of Go routines that read and write a channel. Despite the sophisticated synchronization mechanisms, a deadlock can occur when using channels, which causes the Go runtime environment to terminate the program. A go routine can use the select
construct to listen on several channels at the same time, or try to write in several channels, whereby the case
statement is executed which no longer blocks at first or, in the case of several options, a pseudo-random choice is made.
Data are also kanal <- Wert
written to and variable = <-kanal
read in a channel , whereby the variable assignment can be omitted when reading. Listening to a channel can also be for
automated with the construct, whereby the loop is exited as soon as the channel is closed.
Example:
package main
import "fmt"
func zehnMal(kanal chan string) {
// Argument empfangen
sag := <-kanal
// Zehnmal zurückschreiben
for i := 0; i < 10; i++ {
kanal <- sag
}
// Kanal schließen
close(kanal)
}
func main() {
// synchronen Kanal öffnen
kanal := make(chan string) // oder make(chan string, 0)
// Starten der parallelen Go-Routine „zehnMal()“
go zehnMal(kanal)
// Senden eines Strings
kanal <- "Hallo"
// Empfangen der Strings, bis der Channel geschlossen wird
for s := range kanal {
fmt.Println(s)
}
fmt.Println("Fertig!")
}
In the example, main()
the Go routine zehnMal()
is called, which returns a received string ten times over the same channel and then closes it. Due to the synchronous channel, the two go routines wait for each other so that main()
the for
loop does not enter the loop until zehnMal()
the string has been received. If the channel were not synchronous, a deadlock could occur if main () immediately reads the written variable again (and removes it from the buffer) and zehnMal()
waits in vain for its argument. It is also important that zehnMal()
the channel closes after the strings have been written, main()
otherwise the loop cannot exit.
Implementations
There are at least two compilers for Go that can run on Linux , macOS , Windows and FreeBSD and that fully implement the Go-1 specification:
- Gc
- is the official Go compiler and was initially written in C by Ken Thompson, based on the Plan 9 toolchain and used Yacc / Bison for parsing . With version 1.5 this compiler was translated from C to Go and is therefore self-hosting . The compiler originally consisted of several executable commands that had different names depending on the target architecture: 8g for x86 , 6g for x86_64 , 5g for ARM . With version 1.5 these were combined into a single executable command ( go tool compile ), and the target architecture can be selected via the environment variable GOARCH .
- Gccgo
- by Ian Taylor is a Go frontend for the GNU Compiler Collection (GCC). The front end, written in C ++ , uses a recursive descent for parsing . The following backend steps are those of standard GCC processing. This procedure increases the compilation time compared to the Gc compiler, but the code produced is more efficient. The GNU Compiler Collection (GCC) fully supports Go 1 with version 4.7.1, the GNU Debugger (gdb) supports Go from version 7.5.
Both compilers implement parallel mark-and-sweep garbage collection .
The official compiler is accompanied by the command line tool go , which serves as a facade for various tools, such as B. installing packages from source code repositories on the Internet such as GitHub or Google Code (go get) , automatically formatting source code (go fmt) , running tests (go test) , generating documentation from source text comments (go doc) or compiling the project (go build) , so that no makefiles are necessary if a recommended directory structure is adhered to.
history
The design phase began on September 21, 2007, initially as a 20 percent project on the initiative of Robert Griesemer, Rob Pike and Ken Thompson. Soon after, more developers joined and Go became a full-time project. On October 30, 2009, Go was presented by Rob Pike in a Google TechTalk and announced the release as free software , which then took place on November 10, as announced. Since then, numerous contributions have been made by developers from the Go community outside of Google. Version 1 was released on March 28, 2012. Since then, the language specification and standard library have been considered stable and should remain downward compatible at the source code level within the 1.x series. Go 1.1 was released on May 14, 2013, which mainly contains performance improvements to the implementation. Versions Go 1.2 to Go 1.10 were released six months later.
From April 24 to 26, 2014, the first Go conference, GopherCon, took place in Denver , which has been taking place annually since then.
mascot
The Go mascot is a pocket rat (English gopher ). It was designed by Renée French, who also designed Glenda, the Plan 9 bunny. The logo and the mascot are under the Creative Commons Attribution 3.0 license.
literature
- Alan AA Donovan, Brian W. Kernighan: The Go Programming Language . Pearson Education, 2015, ISBN 978-0-13-419044-0 .
- Frank Müller: System programming in Google Go: basics, scalability, performance, security . dpunkt.verlag, Heidelberg 2011, ISBN 978-3-89864-712-0 .
- Rainer Feike: Programming in Google Go: News from Google in system programming . Addison-Wesley, Munich / Boston 2010, ISBN 978-3-8273-3009-3 .
- Caleb Doxsey: An Introduction to Programming in Go . 2012, ISBN 978-1-4783-5582-3 .
- Andreas Schröpfer: Go - The practical book . dpunkt.verlag, 2020, ISBN 978-3-86490-713-5 .
Web links
-
Official website (English)
- Specification (English)
- An interactive introductory tour (English)
- Translations (German)
- Go at Google: Language Design in the Service of Software Engineering - Article by Rob Pike on language design
- Lecture by Rob Pike on October 30, 2009 ( presentation slides (PDF; 242 kB))
- Programming with Go (ADMIN magazine)
- Go by example (english)
- The Golang-Spicker - compact overview (German)
Individual evidence
- ↑ golang.org .
- ↑ Google-go-language
- ↑ Why Learn Go? - Short interview with Rob Pike (video, English)
- ↑ talks.golang.org
- ↑ golang.org
- ↑ Origins of Go's Concurrency Model
- ↑ Golem.de article Go - fast programming language from Google
- ↑ golang.org
- ↑ golang.org
- ↑ blog.golang.org
- ↑ The Go Playground (example for the parallel calculation of Pi)
- ↑ A Tour Of Go Pointers
- ↑ golang.org
- ↑ golang.org
- ↑ golang.org/doc/faq#Implementation
- ↑ GCC 4.7 Release Series Changes, New Features, and Fixes
- ↑ GDB 7.5 Release Notes
- ↑ Information about the story in the official FAQ
- ^ Original message about the publication in the Google Open Source Blog
- ^ IX article of November 11, 2009
- ↑ Release of version 1 in the Go Programming Language Blog
- ↑ golang.org
- ↑ blog.golang.org
- ↑ GopherCon