Main characteristics
- Compiled
- Garbage Collection
- Static type checking
- Syntax similar to C
- Built-in concurrency primitives (goroutines, channels)
- Emphasis on greater simplicity and safety
It was developed in 2007 by Robert Griesemer, Rob Pike and Ken Thompson at Google but launched in 2009 as an open-source programming language.
Concurrency is very hard in C, golang was born the help in this sense.
Go development using dependencies beyond the standard library is done using Go modules.
When using Go modules, the GOPATH
variable (which defaults to $HOME/go
on Unix and %USERPROFILE%\go
on Windows) is used for the following purposes:
go install
command installs binaries to $GOBIN
, which defaults to $GOPATH/bin
.go get
command caches downloaded modules in $GOMODCACHE
, which defaults to $GOPATH/pkg/mod
.go get
command caches downloaded checksum database state in $GOPATH/pkg/sumdb
.A module is a collection of Go packages stored in a file tree with a go.mod
file at its root.
The go.mod
file defines the module’s module path, which is also the import path used for the root directory of the project, and its dependency requirements, which are the other modules needed for a successful build. Each dependency requirement is written as a module path and a specific semantic version.
Programs start running in package main
Import other modules
cmd/main.go
You can set your dependencies in go.mod file
go.mod
Build the project to a binary:
go build .
Run without generating a binary:
go run main.go
Execute tests:
go test
or go test ./...
Install binaries from github:
go install github.com/norwoodj/helm-docs/cmd/helm-docs@latest
Depending on the container you must compile with different libs, like alpine that only suports musl. In that case you must compile the golang binary inside the container for better compatibility.
// Boolean
var boolean bool // Declaration only
boolean = true // Attribution only
another_bool := false // Declare and attribute infering type
var another_one bool = true // Declare type and Atribution
complex64 // complex numbers with float32 real and imaginary parts
complex128 // complex numbers with float64 real and imaginary parts
byte // alias for uint8
rune // alias for int32
unsigned
is only for positive numbers
// Numeric
uint8 // unsigned 8-bit integers (0 to 255)
uint16 // unsigned 16-bit integers (0 to 65535)
uint32 // unsigned 32-bit integers (0 to 4294967295)
uint64 // unsigned 64-bit integers (0 to 18446744073709551615)
int8 // signed 8-bit integers (-128 to 127)
int16 // signed 16-bit integers (-32768 to 32767)
int32 // signed 32-bit integers (-2147483648 to 2147483647)
int64 // signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
float32 // IEEE-754 32-bit floating-point numbers
float64 // IEEE-754 64-bit floating-point numbers
Using :=
the type is inferred automatically
A string type represents the set of string values. A string value is a (possibly empty) sequence of bytes. The number of bytes is called the length of the string and is never negative. Strings are immutable: once created, it is impossible to change the contents of a string. The predeclared string type is string
; it is a defined type.
An array is a numbered sequence of elements of a single type, called the element type. The number of elements is called the length of the array and is never negative.
var integer_array [10]int
var byte_array [32]byte
var intArr1 [3]int32 // Declaring array of size 3
intArr1[1] = 123 // Set value at index
fmt.Println(intArr[0]) // Accessing array at index
var intArr2 [3]int32 = [3]int32{1,2,3} // Declare an set values
intArr2 := [3]int32{1,2,3} // Infering type and set value
intArr := [...]int32{1,2,3} // Infering size with ...
A slice is a descriptor for a contiguous segment of an underlying array and provides access to a numbered sequence of elements from that array.
A slice type denotes the set of all slices of arrays of its element type.
The value of an uninitialized slice is nil
.
A struct is a sequence of named elements, called fields, each of which has a name and a type.
A function type denotes the set of all functions with the same parameter and result types. The value of an uninitialized variable of function type is nil
.
func()
func(x int) int
func(a, _ int, z float32) bool
func(a, b int, z float32) (bool)
func(prefix string, values ...int)
func(a, b int, z float64, opt ...interface{}) (success bool)
func(int, int, float64) (float64, *[]int)
func(n int) func(p *T)
Golang can return multiple values
“_
” ignores the returned value
This is a common pattern of error handling in golang
func main() {
result, err := withError(200)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err.Error())
os.Exit(1)
}
fmt.Fprintf(os.Stdout, "%v", result)
}
func withError(age int) (string, error) {
if age > 150 {
return "", errors.New("Error: Could not live that long")
}
return fmt.Sprintf("Your age is %d", age), nil
}
An interface type defines a type set. A variable of interface type can store a value of any type that is in the type set of the interface. Such a type is said to implement the interface. The value of an uninitialized variable of interface type is nil
.
A map is an unordered group of elements of one type, called the element type, indexed by a set of unique keys of another type, called the key type. The value of an uninitialized map is nil
.
for i := 0; i < 10; i++ {
sum += i
}
sum := 1
for ; sum < 1000; {
sum += sum
}
// For is Go's "while"
sum := 1
for sum < 1000 {
sum += sum
}
// Forever For
for {
}
// range
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
for _, value := range pow {
fmt.Printf("%d\n", value)
}
func sqrt(x float64) string {
if x < 0 {
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
// can't use v here, though
return lim
}
A defer statement defers the execution of a function until the surrounding function returns.
A pointer type denotes the set of all pointers to variables of a given type, called the base type of the pointer. The value of an uninitialized pointer is nil
.
A pointer holds the memory address of a value.
&
get the memory address.*
get the value stored in a memory address.This is known as “dereferencing” or “indirecting”.
package main
import "fmt"
type Vertex struct {
X, Y float64
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func ScaleFunc(v *Vertex, f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func main() {
v := Vertex{3, 4}
v.Scale(2)
ScaleFunc(&v, 10)
p := &Vertex{4, 3}
p.Scale(3)
ScaleFunc(p, 8)
fmt.Println(v, p)
}
A goroutine is a lightweight thread managed by the Go runtime.
The evaluation of f, x, y, and z happens in the current goroutine and the execution of f happens in the new goroutine.
Channels are a typed conduit through which you can send and receive values with the channel operator, <-
.
(The data flows in the direction of the arrow.)
Like maps and slices, channels must be created before use:
By default, sends and receives block until the other side is ready. This allows goroutines to synchronize without explicit locks or condition variables.
Channels can be buffered.
The select statement lets a goroutine wait on multiple communication operations.
func main(){
d := make(chan int)
quit := make(chan bool)
go func() {
time.Sleep(1 * time.Second)
d <- 1
}()
go func() {
time.Sleep(2 * time.Second)
d <- 2
}()
go func() {
time.Sleep(3 * time.Second)
quit <- true
}()
for {
select {
case msg := <-d:
fmt.Println(msg)
case <-quit:
fmt.Println("Quit")
return
}
}
}
main.go
main_test.go
then execute:
Generate golang test coverage html using the following commands:
# Generate coverage file
$ go test -race -coverprofile=coverage.out ./...
ok example.com/m/slides 0.001s coverage: 50.0% of statements
# Show coverage in command line
$ go tool cover -func=coverage.out
example.com/m/slides/main.go:5: Hello 100.0%
example.com/m/slides/main.go:8: main 0.0%
total: (statements) 50.0%
# Show coverage in HTML
$ go tool cover -html=coverage.out
Go see:
golang is awesome
Comments