The document is an introduction to the Go programming language (Golang) by Markus Schneider, outlining its key features, syntax, and ecosystem. It discusses the language's advantages, such as automatic memory management, strong concurrency support, and rapid compilation, and covers essential syntax elements including types, functions, arrays, slices, maps, and error handling. Additionally, it highlights important tools and libraries in the Golang ecosystem.
Why Go? 01
Somefacts about Go 02
Important Aspects 03
Commands/Syntax Tour 04
Eco-System 05
Summary 06
Q&A/Discussion 07
Agenda
3.
package main
import "fmt"
funcmain() {
fmt.Println("Name: Markus Schneider")
fmt.Println("Company/Business: @ruv_de/Insurance")
fmt.Println("Role: Senior IT Consultant/Cloud Tech.")
fmt.Println("Job: Monitoring/Product Owner")
fmt.Println("IT-Experience: ~20 years")
fmt.Println("Motivation: I like Go!")
fmt.Println("Twitter: @schneidermatic")
fmt.Println("GitHub: http://github.com/schneidermatic")
}
$> whoami
4.
●
Go is anopen-source but backed up by a large corporation
●
Automatic memory management (garbage collection)
●
Strong focus on support for concurrency
●
Fast compilation and execution
●
Statically type, but feels like dynamically typed
●
Good cross-compiling (cross-platform) support
●
Go compiles to native machine code
●
Rapid development and growing community (Docker/Kubernetes)
Why Go?
●
Go is ageneral-purpose language
●
Go is a structured programming language
●
Go is initially developed at Google in 2007
●
Go was announced in November 2009
●
Go is statically typed, compiled language
●
Go is an open source programming language
●
Go 1 was released in March 2012
●
Go is on position 18 according to the TIOBE Index in March 2019
●
Currently, Go 1.12 released in 25 February 2019
Some Facts about Go
7.
●
No type inheritance
●
Nomethod or operator overloading
●
No support for pointer arithmetic
●
No support for Assertions
●
No Exceptions - instead use an error return type
●
No Generics support
●
Dependency management
– Go uses URL based dependency imports
– go get -u golang.org/x/tour
$> tour
– import github.com/somename/somelibrary
Important Aspects
9.
Basic Syntax
package main
import"fmt"
func main() {
fmt.Println("Hello, 世界 ")
}
$> go run HelloWorld.go
Go natively handles Unicode, so it can process text in all the world’s languages
Output: Hello, 世界
Go keywords
●
Go hasonly 25 keywords, even less than german alphabet (26)!
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
12.
Basic types
bool
string
int int8int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // alias for uint8
rune // alias for int32
float32 float64
complex64 complex128
13.
Packages
●
Every Go programis made up of package
●
Program start running in package main
●
Name is exported if it begins with a capital letter
package main
Import (
"fmt"
"math"
)
func main() {
fmt.Println(math.pi) //error
fmt.Println(math.Pi)
}
14.
Functions
func add(x int,y int) int {
return x + y
}
func add(x, y int) int { // when args share the same type,
return x + y // type can be omitted for the first arg
}
func hello(x, y string) (string, string) {
return y, x // return multiple values
}
func hello(x, y string) (a, b string) {
a = x
b = y
return // name return value naked return
}
15.
Variables
●
Use var statementdeclare a list of variables
var c, golang, java bool
func main() {
var i int
}
// variables with initializers
var i, j int = 1, 2
var c, golang, java = false, true, "no!"
●
Inside a functions, the := short assignment can be use in place of var
func main() {
c, golang, java := false, true, "no!"
}
16.
Zero Values
●
Variables declaredwithout initial value are given their zero values
0 for numeric types
false for boolean type
"" for string type
var i int
var f float64
var b bool
var s string
fmt.Printf("%v %v %v %qn", i, f, b, s)
// output: 0 0 false ""
17.
Type Conversion
●
Go assignmentbetween items of different type requires an explicit conversion
var i int = 42
var f float64 = float64(i)
var u unit = unit(f)
●
Constants are declared like variables, but with the const keyword
const Pi = 3.14
Constants
18.
For loop
●
Go hasonly one looping construct, the for loop
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
// note: no () surrounding the three components; {} always required
for is Go’s while
sum := 1
for sum < 1000 {
sum += sum
}
19.
If else
●
If canstart with a short statement to execute before condition
if x := math.Sqrt(100); x < 10 {
fmt.Printf(“Square root of 100 is %vn”, x)
} else {
fmt.Printf(“Square root of 100 is %vn”, x)
}
// note: no () surrounding the condition; {} always required
Switch
●
Switch can startwith a short statement to execute before condition
package main
import (
"fmt"
"runtime"
)
func main() {
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("Go runs on OS X.")
case "linux":
fmt.Println("Go runs on Linux.")
default:
fmt.Printf("Go runs on %s.", os)
}
}
22.
Defer
●
A defer isused to ensure that a function calls is performed late in a program’s execution,
usually for purposes of cleanup. defer is often used where e.g. ensure and finally would
used in other languages
func main() {
f, err := os.Create("/tmp/defer.txt")
defer f.Close()
fmt.Fprintln(f, "Hello, 世界 ")
fmt.Println("counting down")
for i := 0; i < 10; i++ {
defer fmt.Print(i, " ")
}
}
// Output:
counting down
9 8 7 6 5 4 3 2 1 0
23.
Pointer
●
Pointer is avariable whose value is the address of another variable
●
Ampersand (&) operator denotes an address in memory
●
Asterisk (*) operator denotes the pointer's underlying value
func main() {
i := 21
p := &i // store address of i in pointer variable p
fmt.Printf("Address stored in p variable: %pn", p) // print address
fmt.Printf("Value of i is: %vn", *p) // read i through the pointer
*p = 77 // set i through the pointer
fmt.Printf("New value of i is: %vn", i) // see the new value of i
}
// Output:
Address stored in p variable: 0x1040e0f8
Value of i is: 21
New value of i is: 77
24.
Struct
●
struct is acollection of fields
●
struct fields are accessed using a dot
●
struct fields can be accessed through a struct pointer
type Person struct {
Firstname string
Lastname string
}
func main() {
x := Person{"Gordan","Gopher"}
y := &x
y.Firstname := "George"
fmt.Println("My name is %s %s",y.Firstname, y.Lastname)
}
// Output:
My name is George Gopher
25.
Arrays & Slices
●
vara [10]int
●
Array has a fixed size.
●
Slice is a dynamically-size, flexible view of an array; var a []int
primes := [6]int{2, 3, 5, 7, 11, 13}
var s []int = primes[1:4]
fmt.Println(s) // output: [3 5 7]
●
Slice is like reference to array; it does not store any data
names := [4]string{"John", "Paul", "George", "Ringo"}
fmt.Println(names) // [John Paul George Ringo]
a := names[1:3]
fmt.Println(a) // [Paul George]
a[0] = "XXX"
fmt.Println(a) // [XXX George]
fmt.Println(names) // [John XXX George Ringo]
26.
Make function
●
Slices canbe created with the built-in make function; this is how you create
dynamically-sized array
func printSlice(s string, x []int) {
fmt.Printf("%s len=%d cap=%d %vn", s, len(x), cap(x), x)
}
func main() {
a := make([]int, 5) // len(a) = 5; length of a is 5
printSlice("a", a) // output: a len=5 cap=5 [0 0 0 0 0]
b := make([]int, 0, 5) // len(b) = 0, cap(b) = 5
printSlice("b", b) // output: b len=0 cap=5 []
}
27.
Append function
●
Go providesa built-in append function
func main() {
var s []int
printSlice(s) // output: len=0 cap=0 []
s = append(s, 0) // append works on nil slices.
printSlice(s) // output: len=1 cap=2 [0]
s = append(s, 1) // The slice grows as needed.
printSlice(s) // output: len=2 cap=2 [0 1]
s = append(s, 2, 3, 4) // add more than one element at a time
printSlice(s) // output: len=5 cap=8 [0 1 2 3 4]
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %vn", len(s), cap(s), s)
}
28.
Range
●
Range form thefor loop iterates over a slice or map
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
for i, v := range pow {
fmt.Printf("2^%d = %dn", i, v)
}
// Output:
2^0 = 1
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 16
2^5 = 32
2^6 = 64
2^7 = 128
29.
Map
●
make function returnsa map of the given type, initialized and ready to use
m := make(map[string]int) // initialized map
m["Answer"] = 42 // insert element
fmt.Println("The value:", m["Answer"]) // output: The value: 42
m["Answer"] = 48 // update element
fmt.Println("The value:", m["Answer"]) // output: The value: 48
delete(m, "Answer”) // delete element
fmt.Println("The value:", m["Answer"]) // output: The value: 0
v, ok := m["Answer”] // If key is in map, ok is true
fmt.Println("The value:", v, "Present?", ok) // If not, ok is false
// output: The value: 0 Present? false
Methods
●
A method isa function with a special receiver argument
●
Receiver type must be defined in the same package as the method
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
func main() {
f := MyFloat(-21)
fmt.Println(f.Abs()) // Output: 21
}
32.
Pointer receivers
●
Methods withpointer receivers can modify the value to which the receiver points
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func main() {
v := Vertex{3, 4}
fmt.Println(v.Abs()) // Output: 5
v.Scale(10)
fmt.Println(v.Abs()) // Output: 50
}
33.
Interface
●
Interface type isdefined as a set of method signatures
●
A type implements an interface by implementing its methods
●
There is no explicit declaration of intent, no "implements" keyword
type I interface {
M()
}
type T struct {
S string
}
func (t T) M() { // This method means type T implements the interface I
fmt.Println(t.S)
}
func main() {
var i I = T{"hello”}
i.M() // Output: hello
}
34.
Empty interface
●
Interface typethat specifies zero methods is known as the empty interface
●
An empty interface may hold values of any type
●
Ex: fmt.Print takes any number of arguments of type interface{}
func main() {
var i interface{}
describe(i) // Output: (<nil>, <nil>)
i = 42
describe(i) // Output: (42, int)
i = "hello"
describe(i) // Output: (hello, string)
}
func describe(i interface{}) {
fmt.Printf("(%v, %T)n", i, i)
}
35.
Stringer
●
Stringer is definedby the fmt package
type Stringer interface {
String() string
}
●
Stringer is a type that can describe itself as a string
●
fmt package (and many others) look for this interface to print values
type Person struct {
Name string
Age int
}
func (p Person) String() string {
return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}
func main() {
a := Person{"Arthur Dent", 42}
fmt.Println(a) // output: Arthur Dent (42 years)
}
36.
Error
●
The error typeis a built-in interface similar to fmt.Stringer
type error interface {
Error() string
}
type MyError struct {
When time.Time
What string
}
func (e *MyError) Error() string {
return fmt.Sprintf("at %v, %s", e.When, e.What)
}
func run() error {
return &MyError{ time.Now(), "it didn't work” }
}
func main() {
if err := run(); err != nil {
fmt.Println(err) // at 2017-03-08 23:00:00 +0700 ICT, it didn't work
}
}
37.
Panic
●
A panic typicallymeans something went unexpectedly wrong. Mostly we use it to fail fast on
errors that shouldn’t occur during normal operation, or that we aren’t prepared to handle
gracefully.
package main
import "os"
func main() {
// We'll use panic throughout this site to check for
// unexpected errors. This is the only program on the
// site designed to panic.
panic("a problem")
// A common use of panic is to abort if a function
// returns an error value that we don't know how to
// (or want to) handle. Here's an example of
// `panic`king if we get an unexpected error when creating a new file.
_, err := os.Create("/tmp/file")
if err != nil {
panic(err)
}
}
38.
Goroutine
●
Goroutine is alightweight thread managed by the Go runtime
●
Goroutines run in the same address space, so access to shared memory must be synchronized
●
One goroutine usually uses 4 - 5 KB of stack memory
●
Therefore, it's not hard to run thousands of goroutines on a single computer
func say(s string) { // Output:
for i := 0; i < 5; i++ { world
time.Sleep(100 * time.Millisecond) hello
fmt.Println(s) hello
} world
} world
hello
func main() { hello
go say("world”) world
say("hello") world
} hello
39.
Channel
●
Channel is oneof the features that make Golang unique
●
The purpose of using Channel is to transfer values in goroutines
ch <- v // Send v to channel ch
v := <-ch // Receive from ch, and assign value to v
●
Like maps and slices, channels must be created before use:
ch := make(chan int)
40.
Channel: example
●
Sum thenumbers in a slice, distributing the work between two goroutines.
●
Once both goroutines completed their computation, it calculates the final result
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // send sum to c
}
func main() {
s1 := []int{1, 2, 3}
s2 := []int{4, 5, 6}
c := make(chan int)
go sum(s1, c) // [1 2 3]
go sum(s2, c) // [4 5 6]
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y) // output: 15 6 21
}
Blank Identifier
https://kubernetes.io/
Kubernetes –
Is thereanyone out
there who has not heard
of Kubernetes yet? ;)
Kubernetes –
Is there anyone out
there who has not heard
of Kubernetes yet? ;)
53.
●
Go excels inbeing simple and easy to understand
●
Go is a general purpose language and brightly adopted
●
Go is a compiled language and optimized for speed
●
Go has the ability for cross-compiling your application to run on a
different machine than the one used for development
●
Go compiler offers additional benefits like being able to check for errors,
easier deployment and the ability to optimize your code for efficiency
●
Go has strong support for concurrency
●
Go has a rich eco-system and a large community
Conclusion
●
Ease of deployment, strong concurrency and a simple syntax make
Go a great language to build fast, scalable applications
Summary
54.
Thank you
… foryour interest!
Q&A / Discussion
Kudos to the golang community for
information, icons and code samples