JAVA TO GO
GOOGLE GO FÜR JAVA
ENTWICKLER
467.882 ZEILEN CODE
2.130 CONTRIBUTORS
3 GRÜNDE FÜR GO
1 Einfach
2 Mächtig
3 Langweilig
HELLO GOPHER
package main



import "fmt"



func main() {

fmt.Println("Hello Gopher!")
}
Ausführen
go build hellogopher.go // 1. Code kompilieren

./hellogopher // 2. Binary ausführen
go run hellogopher.go // Code kompilieren und ausführen
ENTWICKLUNG
JetBrains
GoLand
Visual
Studio Code
Vim Go
5 FAKTEN ZU GO
1 statisches Typsystem
2 Garbage Collection
3 keine Vererbung
4 Concurrency eingebaut
5 native Ausführung 

Linux, Win, z/OS, 386, amd64, ARM, wasm, ...
VARIABLEN, SLICES, SCHLEIFEN
// Variable
var frank string = "Frank"
claire := "Claire"
1
2
3
4
// Array (fixe Länge)
5
namesArray := [3]string{frank, claire, "Zoe"}
6
7
// Slice (variable Länge)
8
namesSlice := make([]string, 2)
9
namesSlice[0] = frank
10
11
// Schleife
12
for i, name := range namesSlice {
13
fmt.Println("Hello " + name + "!")
14
}
15
// Array (fixe Länge)
namesArray := [3]string{frank, claire, "Zoe"}
// Variable
1
var frank string = "Frank"
2
claire := "Claire"
3
4
5
6
7
// Slice (variable Länge)
8
namesSlice := make([]string, 2)
9
namesSlice[0] = frank
10
11
// Schleife
12
for i, name := range namesSlice {
13
fmt.Println("Hello " + name + "!")
14
}
15
// Slice (variable Länge)
namesSlice := make([]string, 2)
namesSlice[0] = frank
// Variable
1
var frank string = "Frank"
2
claire := "Claire"
3
4
// Array (fixe Länge)
5
namesArray := [3]string{frank, claire, "Zoe"}
6
7
8
9
10
11
// Schleife
12
for i, name := range namesSlice {
13
fmt.Println("Hello " + name + "!")
14
}
15
// Schleife
for i, name := range namesSlice {
fmt.Println("Hello " + name + "!")
}
// Variable
1
var frank string = "Frank"
2
claire := "Claire"
3
4
// Array (fixe Länge)
5
namesArray := [3]string{frank, claire, "Zoe"}
6
7
// Slice (variable Länge)
8
namesSlice := make([]string, 2)
9
namesSlice[0] = frank
10
11
12
13
14
15
STRUCT STATT KLASSE
type Congressman struct {
Name string
}
1
2
3
4
func main() {
5
c := Congressman{Name: "Peter Russo"}
6
fmt.Println("Hello " + c.Name + "!")
7
}
8
c := Congressman{Name: "Peter Russo"}
fmt.Println("Hello " + c.Name + "!")
type Congressman struct {
1
Name string
2
}
3
4
func main() {
5
6
7
}
8
type Congressman struct {
Name string
}
func main() {
c := Congressman{Name: "Peter Russo"}
fmt.Println("Hello " + c.Name + "!")
}
1
2
3
4
5
6
7
8
FUNCTION RECEIVER STATT INSTANZMETHODE
func (c Congressman) swearOathOfOffice() {
fmt.Printf("I, %v, swear to serve the USA.", c.Name)
}
type Congressman struct {
1
Name string
2
}
3
4
5
6
7
8
func main() {
9
c := Congressman{Name: "Peter Russo"}
10
c.swearOathOfOffice();
11
}
12
func (c Congressman) swearOathOfOffice() {
fmt.Printf("I, %v, swear to serve the USA.", c.Name)
}
c := Congressman{Name: "Peter Russo"}
c.swearOathOfOffice();
type Congressman struct {
1
Name string
2
}
3
4
5
6
7
8
func main() {
9
10
11
}
12
INTERFACE
type Greeter interface {
greet()
}
1
2
3
4
func passBy(c1 Greeter, c2 Greeter)
5
c1.greet()
6
c2.greet()
7
}
8
9
func main() {
10
c := Congressman{Name: "Frank U."
11
e := Enemy{}
12
passBy(c, e)
13
}
14
func passBy(c1 Greeter, c2 Greeter)
c1.greet()
c2.greet()
}
type Greeter interface {
1
greet()
2
}
3
4
5
6
7
8
9
func main() {
10
c := Congressman{Name: "Frank U."
11
e := Enemy{}
12
passBy(c, e)
13
}
14
func main() {
c := Congressman{Name: "Frank U."
e := Enemy{}
passBy(c, e)
}
type Greeter interface {
1
greet()
2
}
3
4
func passBy(c1 Greeter, c2 Greeter)
5
c1.greet()
6
c2.greet()
7
}
8
9
10
11
12
13
14
type Greeter interface {
greet()
}
1
2
3
4
func passBy(c1 Greeter, c2 Greeter)
5
c1.greet()
6
c2.greet()
7
}
8
9
func main() {
10
c := Congressman{Name: "Frank U."
11
e := Enemy{}
12
passBy(c, e)
13
}
14
type Congressman struct {

Name string

}


func (c Congressman) greet() {

fmt.Println("Hello", c.Name)

}
type Enemy struct{}



func (e Enemy) greet() {
fmt.Println("Go to hell!") 

}
ZU EINFACH?
STRUCT EMBEDDING STATT VERERBUNG
type Congressman struct {
Name string
}
1
2
3
4
type President struct {
5
Congressman // Embedded
6
7
NuclearWeaponCode string
8
}
9
10
func main() {
11
p := President{NuclearWeaponCode: "123"}
12
p.Name = "Frank Underwood"
13
p.swearOathOfOffice();
14
}
15
type President struct {
Congressman // Embedded
NuclearWeaponCode string
}
type Congressman struct {
1
Name string
2
}
3
4
5
6
7
8
9
10
func main() {
11
p := President{NuclearWeaponCode: "123"}
12
p.Name = "Frank Underwood"
13
p.swearOathOfOffice();
14
}
15
p := President{NuclearWeaponCode: "123"}
p.Name = "Frank Underwood"
p.swearOathOfOffice();
type Congressman struct {
1
Name string
2
}
3
4
type President struct {
5
Congressman // Embedded
6
7
NuclearWeaponCode string
8
}
9
10
func main() {
11
12
13
14
}
15
FEHLER
// Fehler als Rückgabewert
func (c Congressman) bribe(amount float64) error {
if c.Name != "Peter Russo" {
return errors.New("Not corrupt!")
}
c.AccountBalance += amount
return nil
}
1
2
3
4
5
6
7
8
9
func main() {
10
c := Congressman{Name: "Jackie Sharp", AccountBalance: -10.0}
11
12
// Fehler behandeln
13
err := c.bribe(5000.0)
14
if err != nil {
15
fmt.Printf("%v is not bribable.", c.Name)
16
}
17
}
18
// Fehler behandeln
err := c.bribe(5000.0)
if err != nil {
fmt.Printf("%v is not bribable.", c.Name)
}
// Fehler als Rückgabewert
1
func (c Congressman) bribe(amount float64) error {
2
if c.Name != "Peter Russo" {
3
return errors.New("Not corrupt!")
4
}
5
c.AccountBalance += amount
6
return nil
7
}
8
9
func main() {
10
c := Congressman{Name: "Jackie Sharp", AccountBalance: -10.0}
11
12
13
14
15
16
17
}
18
GENERICS
func printSliceOfInts(numbers []int) {

for _, num := range numbers {

fmt.Print(num, " ")

}

}
func printSliceOfStrings(strings []string) {

for _, num := range strings {

fmt.Print(num, " ")

}

}
Generics kommen in Go 2
MÄCHTIG
CONCURRENCY
GOROUTINE
leichtgewichtiger Thread
CHANNEL
Kanal für Nachrichten
GOROUTINE
func main() {
go HelloCongressman("Russo")
}
func HelloCongressman(name string) {
1
fmt.Println("Hello Congressman", name)
2
}
3
4
5
6
7
GOROUTINE MIT SLEEP
func main() {
go HelloCongressman("Russo")
func HelloCongressman(name string) {
1
fmt.Println("Hello Congressman", name)
2
}
3
4
5
6
7
time.Sleep(5 * time.Millisecond)
8
}
9
func main() {
go HelloCongressman("Russo")
time.Sleep(5 * time.Millisecond)
func HelloCongressman(name string) {
1
fmt.Println("Hello Congressman", name)
2
}
3
4
5
6
7
8
}
9
GOROUTINE MIT WAIT GROUP
func main() {
var waitGroup sync.WaitGroup
waitGroup.Add(1)
go func() {
HelloCongressman("Russo")
waitGroup.Done()
}()
waitGroup.Wait()
}
func HelloCongressman() {
1
fmt.Println("Hello Congressman", name)
2
}
3
4
5
6
7
8
9
10
11
12
13
GOROUTINE MIT WAIT GROUP UND DEFER
defer waitGroup.Done()
HelloCongressman("Russo")
func HelloCongressman() {
1
fmt.Println("Hello Congressman", name)
2
}
3
4
func main() {
5
var waitGroup sync.WaitGroup
6
waitGroup.Add(1)
7
go func() {
8
9
10
}()
11
waitGroup.Wait()
12
}
13
CHANNEL
money := make(chan int)
go Congressman(money)
func main() {
1
2
3
4
// Nachricht senden
5
money <- 100
6
}
7
8
func Congressman(money chan int) {
9
// Nachricht empfangen
10
amount := <-money
11
12
fmt.Println("Received", amount, "$!")
13
}
14
// Nachricht senden
money <- 100
func main() {
1
money := make(chan int)
2
go Congressman(money)
3
4
5
6
}
7
8
func Congressman(money chan int) {
9
// Nachricht empfangen
10
amount := <-money
11
12
fmt.Println("Received", amount, "$!")
13
}
14
func Congressman(money chan int) {
// Nachricht empfangen
amount := <-money
fmt.Println("Received", amount, "$!")
}
func main() {
1
money := make(chan int)
2
go Congressman(money)
3
4
// Nachricht senden
5
money <- 100
6
}
7
8
9
10
11
12
13
14
CHANNEL MIT SELECT
func Congressman(money chan int) {
select {
case amount := <-money:
fmt.Println("Received", amount, "$!")
}
}
func main() {
1
money := make(chan int)
2
go Congressman(money)
3
4
// Nachricht senden
5
money <- 100
6
}
7
8
9
10
11
12
13
14
CHANNELMIT TIMEOUT
case <-time.After(1 * time.Second):
fmt.Println("Got nothing ...!")
func main() {
1
money := make(chan int)
2
go Congressman(money)
3
4
time.Sleep(2 * time.Second)
5
}
6
7
func Congressman(money chan int) {
8
select {
9
case amount := <-money:
10
fmt.Println("Received", amount, "$!")
11
12
13
}
14
}
15
time.Sleep(2 * time.Second)
func main() {
1
money := make(chan int)
2
go Congressman(money)
3
4
5
}
6
7
func Congressman(money chan int) {
8
select {
9
case amount := <-money:
10
fmt.Println("Received", amount, "$!")
11
case <-time.After(1 * time.Second):
12
fmt.Println("Got nothing ...!")
13
}
14
}
15
time.Sleep(2 * time.Second)
select {
case amount := <-money:
fmt.Println("Received", amount, "$!")
case <-time.After(1 * time.Second):
fmt.Println("Got nothing ...!")
}
func main() {
1
money := make(chan int)
2
go Congressman(money)
3
4
5
}
6
7
func Congressman(money chan int) {
8
9
10
11
12
13
14
}
15
CONCURRENCY
mit Goroutinen und Channels
STANDARDBIBLIOTHEK
Tests
#
HTTP(2) Server und Router
#
JSON
#
Logging
#
EINFACH
LANGWEILIG
Variablen,
Slices,
Schleifen
Struct
#
#
  

ZU EINFACH?
Struct
Embedding
Fehler
Generics
#
#
#
  

MÄCHTIG
Interface
Goroutine
Channel
Standardbibliothe
#
#
#
#
DEMO
JAN STAMER
Solution Architect
jan.stamer@comdirect.de

JavaForum Nord 2021: Java to Go - Google Go für Java-Entwickler

  • 1.
    JAVA TO GO GOOGLEGO FÜR JAVA ENTWICKLER
  • 3.
  • 5.
    3 GRÜNDE FÜRGO 1 Einfach 2 Mächtig 3 Langweilig
  • 7.
    HELLO GOPHER package main import"fmt" func main() { fmt.Println("Hello Gopher!") } Ausführen go build hellogopher.go // 1. Code kompilieren ./hellogopher // 2. Binary ausführen go run hellogopher.go // Code kompilieren und ausführen
  • 8.
  • 9.
    5 FAKTEN ZUGO 1 statisches Typsystem 2 Garbage Collection 3 keine Vererbung 4 Concurrency eingebaut 5 native Ausführung Linux, Win, z/OS, 386, amd64, ARM, wasm, ...
  • 10.
    VARIABLEN, SLICES, SCHLEIFEN //Variable var frank string = "Frank" claire := "Claire" 1 2 3 4 // Array (fixe Länge) 5 namesArray := [3]string{frank, claire, "Zoe"} 6 7 // Slice (variable Länge) 8 namesSlice := make([]string, 2) 9 namesSlice[0] = frank 10 11 // Schleife 12 for i, name := range namesSlice { 13 fmt.Println("Hello " + name + "!") 14 } 15 // Array (fixe Länge) namesArray := [3]string{frank, claire, "Zoe"} // Variable 1 var frank string = "Frank" 2 claire := "Claire" 3 4 5 6 7 // Slice (variable Länge) 8 namesSlice := make([]string, 2) 9 namesSlice[0] = frank 10 11 // Schleife 12 for i, name := range namesSlice { 13 fmt.Println("Hello " + name + "!") 14 } 15 // Slice (variable Länge) namesSlice := make([]string, 2) namesSlice[0] = frank // Variable 1 var frank string = "Frank" 2 claire := "Claire" 3 4 // Array (fixe Länge) 5 namesArray := [3]string{frank, claire, "Zoe"} 6 7 8 9 10 11 // Schleife 12 for i, name := range namesSlice { 13 fmt.Println("Hello " + name + "!") 14 } 15 // Schleife for i, name := range namesSlice { fmt.Println("Hello " + name + "!") } // Variable 1 var frank string = "Frank" 2 claire := "Claire" 3 4 // Array (fixe Länge) 5 namesArray := [3]string{frank, claire, "Zoe"} 6 7 // Slice (variable Länge) 8 namesSlice := make([]string, 2) 9 namesSlice[0] = frank 10 11 12 13 14 15
  • 11.
    STRUCT STATT KLASSE typeCongressman struct { Name string } 1 2 3 4 func main() { 5 c := Congressman{Name: "Peter Russo"} 6 fmt.Println("Hello " + c.Name + "!") 7 } 8 c := Congressman{Name: "Peter Russo"} fmt.Println("Hello " + c.Name + "!") type Congressman struct { 1 Name string 2 } 3 4 func main() { 5 6 7 } 8 type Congressman struct { Name string } func main() { c := Congressman{Name: "Peter Russo"} fmt.Println("Hello " + c.Name + "!") } 1 2 3 4 5 6 7 8
  • 12.
    FUNCTION RECEIVER STATTINSTANZMETHODE func (c Congressman) swearOathOfOffice() { fmt.Printf("I, %v, swear to serve the USA.", c.Name) } type Congressman struct { 1 Name string 2 } 3 4 5 6 7 8 func main() { 9 c := Congressman{Name: "Peter Russo"} 10 c.swearOathOfOffice(); 11 } 12 func (c Congressman) swearOathOfOffice() { fmt.Printf("I, %v, swear to serve the USA.", c.Name) } c := Congressman{Name: "Peter Russo"} c.swearOathOfOffice(); type Congressman struct { 1 Name string 2 } 3 4 5 6 7 8 func main() { 9 10 11 } 12
  • 13.
    INTERFACE type Greeter interface{ greet() } 1 2 3 4 func passBy(c1 Greeter, c2 Greeter) 5 c1.greet() 6 c2.greet() 7 } 8 9 func main() { 10 c := Congressman{Name: "Frank U." 11 e := Enemy{} 12 passBy(c, e) 13 } 14 func passBy(c1 Greeter, c2 Greeter) c1.greet() c2.greet() } type Greeter interface { 1 greet() 2 } 3 4 5 6 7 8 9 func main() { 10 c := Congressman{Name: "Frank U." 11 e := Enemy{} 12 passBy(c, e) 13 } 14 func main() { c := Congressman{Name: "Frank U." e := Enemy{} passBy(c, e) } type Greeter interface { 1 greet() 2 } 3 4 func passBy(c1 Greeter, c2 Greeter) 5 c1.greet() 6 c2.greet() 7 } 8 9 10 11 12 13 14 type Greeter interface { greet() } 1 2 3 4 func passBy(c1 Greeter, c2 Greeter) 5 c1.greet() 6 c2.greet() 7 } 8 9 func main() { 10 c := Congressman{Name: "Frank U." 11 e := Enemy{} 12 passBy(c, e) 13 } 14 type Congressman struct { Name string } func (c Congressman) greet() { fmt.Println("Hello", c.Name) } type Enemy struct{} func (e Enemy) greet() { fmt.Println("Go to hell!") }
  • 14.
  • 15.
    STRUCT EMBEDDING STATTVERERBUNG type Congressman struct { Name string } 1 2 3 4 type President struct { 5 Congressman // Embedded 6 7 NuclearWeaponCode string 8 } 9 10 func main() { 11 p := President{NuclearWeaponCode: "123"} 12 p.Name = "Frank Underwood" 13 p.swearOathOfOffice(); 14 } 15 type President struct { Congressman // Embedded NuclearWeaponCode string } type Congressman struct { 1 Name string 2 } 3 4 5 6 7 8 9 10 func main() { 11 p := President{NuclearWeaponCode: "123"} 12 p.Name = "Frank Underwood" 13 p.swearOathOfOffice(); 14 } 15 p := President{NuclearWeaponCode: "123"} p.Name = "Frank Underwood" p.swearOathOfOffice(); type Congressman struct { 1 Name string 2 } 3 4 type President struct { 5 Congressman // Embedded 6 7 NuclearWeaponCode string 8 } 9 10 func main() { 11 12 13 14 } 15
  • 16.
    FEHLER // Fehler alsRückgabewert func (c Congressman) bribe(amount float64) error { if c.Name != "Peter Russo" { return errors.New("Not corrupt!") } c.AccountBalance += amount return nil } 1 2 3 4 5 6 7 8 9 func main() { 10 c := Congressman{Name: "Jackie Sharp", AccountBalance: -10.0} 11 12 // Fehler behandeln 13 err := c.bribe(5000.0) 14 if err != nil { 15 fmt.Printf("%v is not bribable.", c.Name) 16 } 17 } 18 // Fehler behandeln err := c.bribe(5000.0) if err != nil { fmt.Printf("%v is not bribable.", c.Name) } // Fehler als Rückgabewert 1 func (c Congressman) bribe(amount float64) error { 2 if c.Name != "Peter Russo" { 3 return errors.New("Not corrupt!") 4 } 5 c.AccountBalance += amount 6 return nil 7 } 8 9 func main() { 10 c := Congressman{Name: "Jackie Sharp", AccountBalance: -10.0} 11 12 13 14 15 16 17 } 18
  • 17.
    GENERICS func printSliceOfInts(numbers []int){ for _, num := range numbers { fmt.Print(num, " ") } } func printSliceOfStrings(strings []string) { for _, num := range strings { fmt.Print(num, " ") } } Generics kommen in Go 2
  • 18.
  • 19.
  • 20.
    GOROUTINE func main() { goHelloCongressman("Russo") } func HelloCongressman(name string) { 1 fmt.Println("Hello Congressman", name) 2 } 3 4 5 6 7
  • 21.
    GOROUTINE MIT SLEEP funcmain() { go HelloCongressman("Russo") func HelloCongressman(name string) { 1 fmt.Println("Hello Congressman", name) 2 } 3 4 5 6 7 time.Sleep(5 * time.Millisecond) 8 } 9 func main() { go HelloCongressman("Russo") time.Sleep(5 * time.Millisecond) func HelloCongressman(name string) { 1 fmt.Println("Hello Congressman", name) 2 } 3 4 5 6 7 8 } 9
  • 22.
    GOROUTINE MIT WAITGROUP func main() { var waitGroup sync.WaitGroup waitGroup.Add(1) go func() { HelloCongressman("Russo") waitGroup.Done() }() waitGroup.Wait() } func HelloCongressman() { 1 fmt.Println("Hello Congressman", name) 2 } 3 4 5 6 7 8 9 10 11 12 13
  • 23.
    GOROUTINE MIT WAITGROUP UND DEFER defer waitGroup.Done() HelloCongressman("Russo") func HelloCongressman() { 1 fmt.Println("Hello Congressman", name) 2 } 3 4 func main() { 5 var waitGroup sync.WaitGroup 6 waitGroup.Add(1) 7 go func() { 8 9 10 }() 11 waitGroup.Wait() 12 } 13
  • 24.
    CHANNEL money := make(chanint) go Congressman(money) func main() { 1 2 3 4 // Nachricht senden 5 money <- 100 6 } 7 8 func Congressman(money chan int) { 9 // Nachricht empfangen 10 amount := <-money 11 12 fmt.Println("Received", amount, "$!") 13 } 14 // Nachricht senden money <- 100 func main() { 1 money := make(chan int) 2 go Congressman(money) 3 4 5 6 } 7 8 func Congressman(money chan int) { 9 // Nachricht empfangen 10 amount := <-money 11 12 fmt.Println("Received", amount, "$!") 13 } 14 func Congressman(money chan int) { // Nachricht empfangen amount := <-money fmt.Println("Received", amount, "$!") } func main() { 1 money := make(chan int) 2 go Congressman(money) 3 4 // Nachricht senden 5 money <- 100 6 } 7 8 9 10 11 12 13 14
  • 25.
    CHANNEL MIT SELECT funcCongressman(money chan int) { select { case amount := <-money: fmt.Println("Received", amount, "$!") } } func main() { 1 money := make(chan int) 2 go Congressman(money) 3 4 // Nachricht senden 5 money <- 100 6 } 7 8 9 10 11 12 13 14
  • 26.
    CHANNELMIT TIMEOUT case <-time.After(1* time.Second): fmt.Println("Got nothing ...!") func main() { 1 money := make(chan int) 2 go Congressman(money) 3 4 time.Sleep(2 * time.Second) 5 } 6 7 func Congressman(money chan int) { 8 select { 9 case amount := <-money: 10 fmt.Println("Received", amount, "$!") 11 12 13 } 14 } 15 time.Sleep(2 * time.Second) func main() { 1 money := make(chan int) 2 go Congressman(money) 3 4 5 } 6 7 func Congressman(money chan int) { 8 select { 9 case amount := <-money: 10 fmt.Println("Received", amount, "$!") 11 case <-time.After(1 * time.Second): 12 fmt.Println("Got nothing ...!") 13 } 14 } 15 time.Sleep(2 * time.Second) select { case amount := <-money: fmt.Println("Received", amount, "$!") case <-time.After(1 * time.Second): fmt.Println("Got nothing ...!") } func main() { 1 money := make(chan int) 2 go Congressman(money) 3 4 5 } 6 7 func Congressman(money chan int) { 8 9 10 11 12 13 14 } 15
  • 27.
  • 28.
  • 29.
  • 30.
  • 32.