Slide 1

Slide 1 text

Java User Group Saarland Go for Java Developers Thomas Darimont eurodata AG 35. Meeting 27. February 2018 Sponsored by

Slide 2

Slide 2 text

Let’s Go https://github.com/egonelbre/gophers/blob/master/sketch/superhero/flying.png

Slide 3

Slide 3 text

What is Go? ● Open Source Programming Language created by Google in 2007 ○ Robert Griesemer, Rob Pike, and Ken Thompson ○ Unix, C, UTF-8, Plan 9 ○ Current Version 1.10 ● Main design goal ○ Focus on simplicity - not many features ○ Philosophy: “Less is exponentially more” ● Main purpose ○ Initially: System tools programming ○ Nowadays: CLI & Backend Applications ● Language of the Cloud ○ Highly performant and scalable ○ Efficient ○ Built-in concurrency support ○ Easy to read and to maintain ○ Support for multiple OS 3

Slide 4

Slide 4 text

Why learn Go? ● Learning a new Programming Languages makes you a better programmer ○ Go maybe a better choice than Java in certain situations ● Contribute or integrate with existing Go Projects ○ Kubernetes, Docker, Cloud Foundry,... ● Increasing demand for developers proficient in Go ● Companies that use Go ○ Google, Dropbox, Pivotal, Microsoft, Sixt, Facebook, Twitter ○ https://github.com/golang/go/wiki/GoUsers 4

Slide 5

Slide 5 text

Go and Java Similarities ● Fast ○ Almost as fast as C ○ Faster than C in some cases ● C-style ● Imperative ● Compiled ● Statically typed ● Object-oriented ● Cross-platform ● Garbage collection ● Memory safety ● Type assertions ● Reflection ● Packages and Imports 5

Slide 6

Slide 6 text

Go and Java Differences ● No VM ○ Programs are compiled ahead of time to native machine code ○ Executed on the processor directly ● Small language ● Syntax differences ● Built-in strings, arrays and maps ● Type inference ● “real” Closures ● Concurrency via CSP (Communicating Sequential Processes) ● No Classes ● No Inheritance, no type hierarchy ● No Annotations ● No Generics ● No Overloaded Methods 6

Slide 7

Slide 7 text

Why is Go so different? ● “Language design in the service of software engineering” ● Familiar, yet modern ● High performance, compiler and runtime ● Balance between complexity and convenience ● Emphasis on automated tools 7

Slide 8

Slide 8 text

Runtime ● Compiled into every executable go program ○ Runtime ~ 1MB ○ No other dependencies required, e.g. no libc ○ Single executable binary, allows small Docker images ● Garbage Collection ● Concurrency ● Stack Management ● Extensive library ○ “Batteries included” ○ Go’s runtime is analogous to libc, the C library 8

Slide 9

Slide 9 text

Hello World! package main import "fmt" func main() { fmt.Println("Hello, JUGSaar") } 9 $ go run hello_world.go Hello, JUGSaar

Slide 10

Slide 10 text

Keywords 10 break func select case go struct chan goto switch const if type continue import var default interface defer map else package fallthrough range for return Java 1.8 (42*) Go 1.10 (25*) abstract else instanceof strictfp assert enum interface super break extends native switch case final new synchronized catch finally package this class for private throw const goto protected throws continue if public transient default implements return try do import static void volatile while *) Without built-in types

Slide 11

Slide 11 text

Using Package package main import ( "fmt" "math/rand" ) func main() { fmt.Println("My favorite number is: ", rand.Int(10)) } 11 One can also import packages with separate lines import "fmt" import "math/rand"

Slide 12

Slide 12 text

Exported Names acme.PrintSomething("hello") // exported 12 ● In Go, a symbol is exported if it begins with a capital letter. acme.printSomethingElse("world") // not exported ● Use... ● Instead of

Slide 13

Slide 13 text

Variables package main import "fmt" var x, y, z int func main() { var c, python, java = true, false, "no!" haskell, clojure, sml := true, true, true fmt.Println(x,y,z,c,python, java, haskell, clojure, sml) } 13 using := construct, we can omit var keyword and type! “short-form” type can be omitted, since compiler can guess it from the value expression

Slide 14

Slide 14 text

Basic Data Types ● Go has a set of basic types and pointers ○ byte, int (signed, unsigned), float ○ bool ○ rune represents Unicode codepoint ○ string ○ complex support for complex numbers ● Go has also Pointers, but no pointer arithmetic ○ Pointers in Go are treated similar to references in Java ○ Purpose: Pass large data sets efficiently around ○ uintptr ■ integer type large enough to hold any pointer ○ var p *string = &s ■ * denotes a pointer type, C-style dereferencing ■ & C-style “address-of” operator 14 Go type Java Type int8 / byte byte int16 short int32 (int/rune) int int64 long float32 float float64 double Numeric Types in Go and Java

Slide 15

Slide 15 text

Constants package main import "fmt" const Pi = 3.0 func main() { const World = "世界" fmt.Println("Hello", World) fmt.Println("Happy", Pi, "Day") const Truth = true fmt.Println("Go rules?", Truth) } 15

Slide 16

Slide 16 text

Grouping Variables and Constants import "math/cmplx" var ( ToBe bool = false MaxInt uint64 = 1<<64 - 1 z complex128 = cmplx.Sqrt(-5 + 12i) ) const ( Big = 1 << 100 Small = Big >> 99 ) 16

Slide 17

Slide 17 text

Functions package main import "fmt" func add(x int, y int) int { return x + y } func add_and_sub(x, y int) (int, int) { return x + y, x - y } func main() { fmt.Println(add(42, 13)) a, b := add_and_sub(42, 13) fmt.Println(a, b) } 17 parameter name type return type parameter name type multiple return types receiving multiple return values

Slide 18

Slide 18 text

Functions - Named results package main import "fmt" func split(sum int) (x, y int) { x = sum * 4/9 y = sum - x return } func main() { fmt.Println(split(17)) } 18

Slide 19

Slide 19 text

Error Handling ● Functions declare second return value of type error (error is an interface) ○ If error happened, then return default value and error ○ If no error happened, then return actual value and nil as error ● Go has no Exceptions so error handling happens by checking for errors ● Syntax for Checking for errors is a bit awkward… 19 func f() (int, error) { … if errorHappened { return 0, fmt.Errorf(“...”) } … return 1, nil } n, err := f() if err != nil [ … handle error return } // can safely use n

Slide 20

Slide 20 text

Functions - First Class Citizens func main() { hypot := func(x, y float64) float64 { return math.Sqrt(x*x + y*y) } fmt.Println(hypot(3,4)) } 20 Creates a anonymous (lambda) function and assign it to a variable Functions in Go are first class citizens, which means that you can pass them around like values.

Slide 21

Slide 21 text

Closures func fibonacci() func() int { x, y := 0, 1 return func() int { x, y = x+y, x return x } } func main() { f := fibonacci() for i := 0; i < 10; i++ { fmt.Println(f()) } } 21 Go uses lexical closures, which means a function is evaluated in the environment where it is defined. x and y are accessible inside the anonymous function!

Slide 22

Slide 22 text

For loop func main() { sum := 0 for i := 0; i < 10; i++ { sum += i } for ;sum < 1000; { sum += sum } for sum < 10000 { sum += sum } fmt.Println(sum) for { fmt.Println("4ever") } } 22 similar to Java but without parentheses Go does not have a while loop! While loops are for loops! Infinite loop!

Slide 23

Slide 23 text

Conditionals: If package main import "fmt" func main() { a := 10 if a > 1 { fmt.Println("if true") } if b := 123 * 456; b < 10000 { fmt.Println("another one, but with short statement") } } 23 short statement, b is only visible inside if block!

Slide 24

Slide 24 text

Conditionals: Switch import "fmt" import "runtime" func main() { fmt.Print("Go runs on ") switch os := runtime.GOOS; os { case "darwin": fmt.Println("OS X.") case "linux": fmt.Println("Linux.") default: fmt.Printf("%s.", os) } } 24 Just like if, you can use the short form here Switch cases evaluate from top to bottom, stopping when a case succeeds. No automatic fall-through! → Fall-through via fallthrough keyword

Slide 25

Slide 25 text

Switch Without Condition import "fmt" import "runtime" t := time.Now() switch { case t.Hour() < 12: fmt.Println("Good morning!") case t.Hour() < 17: fmt.Println("Good afternoon.") default: fmt.Println("Good evening.") } 25 no condition Like writing long if/else chains

Slide 26

Slide 26 text

Structs package main import "fmt" type Vertex struct { X int Y int } func main() { v := Vertex{1,2 } v.X = 4 fmt.Println(v) } 26 A struct is a collection of fields. Struct fields are accessed using a dot. Go’s mechanism for composing types

Slide 27

Slide 27 text

Structs package main import "fmt" type Vertex struct { X int Y int } func main() { v := Vertex{1,2 } v.X = 4 p := &v fmt.Println(v.X, p.X) } 27 p has a pointer to v, which has type *Vertex Use dot to access field of a pointer

Slide 28

Slide 28 text

The new Function package main import "fmt" type Vertex struct { X,Y int } func main() { v := new(Vertex) fmt.Println(v) v.X, v.Y = 11, 9 fmt.Println(v) } 28 The expression new(T) allocates a zeroed T value and returns a pointer to it. v has type:; *Vertex

Slide 29

Slide 29 text

Arrays VS. Slices ● Arrays have a fixed length and are mutable ○ Syntax [length]type, c.f. [2]string ○ Similar to typed arrays in Java, c.f. int[] ○ Length of arrays is part of the type … makes it less useful ○ Examples ■ a := [2]string{"aaa","bbb"} ■ languages := [...]string{"german", "english", "french"} // size determined by elements ● Slices are dynamically sized and mutable ○ Syntax []type, c.f. []string ○ Similar to ArrayList in Java ○ can be grown dynamically ■ s := make([]string, 3) ■ s = append(s, "a", "b", "c", "d") ○ Examples ■ s := []string{} ■ s := []string{"aaa", "bbb"} // slice literal 29

Slide 30

Slide 30 text

Slices package main import "fmt" func main() { p := []int{2, 3, 5, 7, 11, 13} // slice literal fmt.Println("p == ", p) fmt.Println("p == ", p[1:4]) // [3 5 7] fmt.Println("p == ", p[:3]) // [2 3 5] fmt.Println("p == ", p[4:]) // [11 13] for i := 0; i < len(p); i++ { fmt.Printf("p[%d] == %d\n", i, p[i]) } } 30 A slice points to an array of values and also includes a length. The zero value of a slice is nil

Slide 31

Slide 31 text

Maps package main import "fmt" type Vertex struct { Lat, Long float64 } func main() { m := make(map[string]Vertex) m["Bell Labs"] = Vertex{40.68433, -74.39967} fmt.Println(m["Bell Labs"]) } 31 A map maps keys to values. Maps can be created with make (not new) before use; the nil map is empty and cannot be assigned to.

Slide 32

Slide 32 text

Map Literals package main import "fmt" type Vertex struct { Lat, Long float64 } func main() { m := map[string]Vertex { "Bell Labs": Vertex{40.68433, -74.39967}, } fmt.Println(m["Bell Labs"]) } 32 trailing comma!

Slide 33

Slide 33 text

Mutating Maps m := map[string]Vertex { "Bell Labs": Vertex{40.68433, -74.39967}, } // Add element m["Google"] = Vertex{40.68533, -74.3367} // Test if Key exists n, ok := m["Intel"] if ok { fmt.Println("key exists!") } // Delete an item delete(m, "Google") 33

Slide 34

Slide 34 text

Iterating through Slices or Maps package main import "fmt" func main() { nums := []int{2, 3, 5, 7, 11, 13} for i, v := range nums { fmt.Println(i, v) } for _, v := range nums { fmt.Println(v) } } 34 Go provides the range keyword for iteration. Works for slices, arrays, maps and channels. _ ignored value

Slide 35

Slide 35 text

Objects without Classes ● No classes, use interfaces instead ● No inheritance, use embedding instead 35

Slide 36

Slide 36 text

● Methods are functions attached to a type ● It is possible to attach a method to any type - including library types ● Receiver can be named arbitrarily - in Java the receiver is always called this ● Syntax func (RECEIVER) Name(Args) RETURN_TYPE { … } Methods 36 https://play.golang.org/p/UDuOv2loKJj type Stack struct { data []string } func (s *Stack) Push(x string) { s.data = append(s.data, x) } func main() { s := &Stack{} // creates new “instance” of Stack s.Push("Hello") s.Push("World") fmt.Println(s) // prints [Hello World] }

Slide 37

Slide 37 text

Method Declaration type Vertex struct { X, Y float64 } func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func main() { v := &Vertex{3, 4} fmt.Println(v.Abs()) } 37 Methods basically look like functions, but with extra receiver declaration before function name.

Slide 38

Slide 38 text

Type embedding import "time" import "fmt" type MyTime struct { time.Time // struct embedding } func (t MyTime) bla() string { return t.Local().String()[0:20] } func main() { mt := &MyTime{} fmt.Println(mt.bla()) } 38 Sort of “Inheritance”...

Slide 39

Slide 39 text

Defer ● Useful construct related to error handling ● similar to try{ … } finally {...} in Java ● Syntax defer callableExpression(argExpressions) ○ argExpressions are evaluated immediately ○ callableExpression is evaluated on block / function exit 39 resp, err := http.Get(url) if err != nil { ... } defer resp.Body.Close() … // resp.Body.Close() invoked before block exit

Slide 40

Slide 40 text

Interfaces ● Very similar to interfaces in Java but more flexible ○ There is no “implements” in Go ● Structural typing ○ A type “implements” / satisfies an interface by declaring matching method signatures ○ Makes it easy to work with libraries 40 func Fprintf(w io.Writer, format string, args ...interface {}) (int, error) { ... } type Writer interface { Write(p []byte) (int, error) } type NopWriter struct { } func (w *NopWriter) Write(p []byte) (int, error) { return len(p), nil } var w NopWriter fmt.Fprintf(&w, “Hello, World!”)

Slide 41

Slide 41 text

Concurrency ● Go uses a CSP model (Communicating Sequential Processes) ○ State is passed as messages through Channels between concurrent processes ○ Go Proverb: Don’t communicate by sharing memory, share memory by communicating ● Unit of execution is a Go Routine ○ Scheduled by the Go Runtime on a M-N threading model ○ Similar to Green Threads in former Java versions ○ Context switching is very cheap ● Go Routines are started via the go keyword ○ Every function can be executed in a Go Routine 41 func say(s string) { fmt.Println(s) } go say(“hi”) say(“there”)

Slide 42

Slide 42 text

Channels ● Can be uni-directional (r or w) or bidirectional (rw) ● Send / Receive Operations are blocking … unless the channel is configured with a buffer. ● So somebody on the other side must receive / accept the value before you can continue. ○ Makes channels a good synchronization mechanism 42 https://play.golang.org/p/3Boc_djIBVE ch := make (chan int) // create channel ch <- x //send x = <- ch //receive and assign <-ch // receive and discard close (ch) // closes the channel

Slide 43

Slide 43 text

Select ● Select will execute whatever which blocking operation is ready to receive… ○ can also wait for timeout and do something else… 43 https://play.golang.org/p/E4RMck62dWf select { case <- ch1: // receive … case x:= <- ch2: // receive and assign … default: ... }

Slide 44

Slide 44 text

Tools ● go ○ Think of java, javac, maven + gradle in one tool ● go run ● go build ● go install ● go test ● go get ● go vet ● gofmt ● goimports ● godep (dep) 44

Slide 45

Slide 45 text

Books 45

Slide 46

Slide 46 text

Conclusion ● Go is similar to Java yet very different ● Go is simple, elegant, and efficient ● Go is worth giving a try 46

Slide 47

Slide 47 text

Links ● Code & Slides https://github.com/jugsaar/jugsaar-35-go4java-developers ● Website https://golang.org ● Playground https://play.golang.org ● Language Specification https://golang.org/ref/spec ● GoTime FM Podcast https://changelog.com/gotime 47