74
Golang basics… ...for Java developers Robert Stern

Golang basics for Java developers - Part 1

Embed Size (px)

Citation preview

Page 1: Golang basics for Java developers - Part 1

Golang basics…...for Java developers

Robert Stern

Page 2: Golang basics for Java developers - Part 1

Agenda

Overview

Basic syntax and structure

Datatypes

Flow control

Functions, interfaces

Java vs. Go

Page 3: Golang basics for Java developers - Part 1

All you need is…

https://play.golang.org/

Page 4: Golang basics for Java developers - Part 1

Overview

Basic syntax and structure

Datatypes

Flow control

Functions, interfaces

Concurrency

Java vs. Go

Page 5: Golang basics for Java developers - Part 1

History and features

Created in 2007 at Google, announced in 2009, v1.0 released in 2012) with strong dedication for server side programming.

Compiled, statically typed, garbage collected language with multiple architecture/OS support (i386, amd64, arm/Windows, Linux, *BSD, etc..)

(very) fast compilation AND execution time with low resource consumption

Powerful cli (go get, go build, go test, go install…)

Current stable version is 1.6.3 and still being actively developed

Page 6: Golang basics for Java developers - Part 1

What is missing or disturbing?

No generics

Not an OO language

No constructors

No operator/method overloading

No circular package imports

No mandatory semicolons

GC pause is unpredictable

Page 7: Golang basics for Java developers - Part 1

What is non-java-isch?

Multiple return values + the blank variable

Golang is a pass-by-value language

Lightweight concurrency with goroutines and channels

No SE/EE separation. All server stuff is built-in.

No exceptions, use error instead

Compile time error about unused imports and variables

No maven/ant like build system. Uses Makefile+vendoring+go get

Page 8: Golang basics for Java developers - Part 1

Famous projects, companies

Projects:

App Engine with Go, AWS with Go SDK, Docker, Kubernetes, Grafana, Terraform, Gogs (Go Git Service), etcd, drone.io, Syncthing, CockroachDB, rkt, nsq, consul, boltDB, weave, swarm, vulcand, gryffin, fleet, minio…

Companies:

Google (of course…), Netflix, Dropbox, CloudFlare, SoundCloud, BBC, Uber, Couchbase, MongoDB...

Page 9: Golang basics for Java developers - Part 1

Google trends - golang

Page 10: Golang basics for Java developers - Part 1

A bit bigger picture about the trends

Page 11: Golang basics for Java developers - Part 1

Overview

Basic syntax and structure

Datatypes

Flow control

Functions, interfaces

Concurrency

Java vs. Go

Page 12: Golang basics for Java developers - Part 1

Hello world in golang:

package main

// imports

import "fmt"

/*

This is the main function

*/

func main() {

fmt.Println("Hello, World!")

}

Try it in the Go playground!

Hello world

Page 13: Golang basics for Java developers - Part 1

Go project structure

❏ Workspace ($GOPATH or %GOPATH%)

❏ src/pkg/bin roots

❏ Repository (github.com, etc…)

❏ Package

❏ Go source files

Page 14: Golang basics for Java developers - Part 1

Structure example

Page 15: Golang basics for Java developers - Part 1

PackagesLike in Java, golang also uses packages to organize code, but in a bit different format.

Keyword: package <name>

The app starts in the main package.

the path to the package’s directory is the import path

The package name is the last element of the import path:

github.com/zooplus/golang-app/stringutil → stringutil

Accessing stringutil functions/elements: stringutil.<name>

Page 16: Golang basics for Java developers - Part 1

import ("reflect""strings""github.com/emicklei/go-restful"

)

import "reflect"import "strings"import "github.com/emicklei/go-restful"

Importing packages

Page 17: Golang basics for Java developers - Part 1

Package typesTo use one or more functions in a package we need to import it into our code. We can import system, local and remote packages.

System packages are the golang out of box packages like http, testing, etc..

Local package resides in your repository, no full path needed

Remote packages has complete import path pointing to the server like: github.com/emicklei/go-restful

Page 18: Golang basics for Java developers - Part 1

Getting the dependenciesFor remote packages use go get to fetch into your workspace. We have two syntaxes

go get in the repository folder downloads all remote packages based on the imports

go get <remote path> downloads the specified package for later use

Page 19: Golang basics for Java developers - Part 1

Variables, constantspackage main

import "fmt"

const greeting = "Hello"

var name string

func main() {name = "Zooplus"space := " " fmt.Println(greeting + space + name)

}

Page 20: Golang basics for Java developers - Part 1

if _, err := os.Stat(path); os.IsNotExist(err) {fmt.Printf("%s does not exist\n", path)

}

The blank identifier“The blank identifier can be assigned or declared with any value of any type, with the value discarded harmlessly”

(https://golang.org/doc/effective_go.html#blank)

Page 21: Golang basics for Java developers - Part 1

Exported names“In Go, a name is exported if it begins with a capital letter.

For example, Pizza is an exported name, as is Pi, which is exported from the math package.”

package main

import ("fmt""math"

)

func main() {fmt.Println(math.pi)

}

Page 22: Golang basics for Java developers - Part 1

Practice!Refactor the greeting app to use fmt.Printf(format, args...)** and display the following message:

Hello Zooplus, today is Friday.

The name of the day as string can be printed with:

import "time"

...time.Now().Format("Monday")

**(Use %s for string)

Page 23: Golang basics for Java developers - Part 1

A solutionpackage main

import ("fmt""time"

)

func main() {name := "Zooplus"fmt.Printf("Hello %s, today is %s.", name, time.Now().Format("Monday"))

}

Page 24: Golang basics for Java developers - Part 1

Overview

Basic syntax and structure

Datatypes

Flow control

Functions, interfaces

Concurrency

Java vs. Go

Page 25: Golang basics for Java developers - Part 1

Basic typesbool

string

int int8 int16 int32 int64

uint uint8 uint16 uint32 uint64 uintptr

byte // alias for uint8

rune // alias for int32, represents a Unicode code point

float32 float64

complex64 complex128 - “math/cmplx”:

var number complex128 = cmplx.Sqrt(-5 + 12i)

Page 26: Golang basics for Java developers - Part 1

Pointers - bit.ly/2a58jnIpackage main

import "fmt"

func main() {i, j := 42, 2701

p := &i // point to ifmt.Println(*p) // read i through the pointer*p = 21 // set i through the pointerfmt.Println(i) // see the new value of i

p = &j // point to j*p = *p / 37 // divide j through the pointerfmt.Println(j) // see the new value of j

}

Page 27: Golang basics for Java developers - Part 1

package main

var (a intb int32c int16

)

func main() {a = 1b = ac = a

}

No autoboxing! You should convert your types by yourself.

package main

import "fmt"

var (a intb int32c int16

)

func main() {a = 1b = int32(a)c = int16(a)fmt.Printf("a: %d, b: %d, c: %d", a, b, c)

}

Type conversion

prog.go:11: cannot use a (type int) as type int32 in assignmentprog.go:12: cannot use a (type int) as type int16 in assignmenta: 1, b: 1, c: 1

Page 28: Golang basics for Java developers - Part 1

Structtype ApacheLogRecord struct {

ip string

time string

method, uri, protocol string

status intresponseBytes intreferer

stringuserAgent

string}

1. result = &ApacheLogRecord{ip:

nvl(req.RemoteAddr),time: timeFormatted,method:

nvl(req.Method),uri:

nvl(req.URL.Path),protocol: nvl(req.Proto),status:

resp.StatusCode(),responseBytes:

resp.ContentLength(),referer:

nvl(req.Referer()),userAgent:

nvl(req.UserAgent()),}2.) result = new(ApacheLogRecord)

Page 29: Golang basics for Java developers - Part 1

package main

import "fmt"

type Animal struct { legCount int }// define a behavior for Animalfunc (a Animal) numberOfLegs() int { return a.legCount}

type Dog struct { Animal //anonymous field Animal}

func main() { d := Dog{Animal{4}} //no method defined for Dog, but we have the same behavior as Animal. fmt.Println("A Dog has this many legs: ", d.numberOfLegs()) }

Embedding, inheritance -bit.ly/2axY1yu

Page 30: Golang basics for Java developers - Part 1

Receiver methods -bit.ly/2a56VkSpackage mainimport "fmt"type Animal struct {

legCount int}func (a Animal) numberOfLegs() int {

return a.legCount}func (a Animal) setLegs(c int) {

a.legCount = c}type Mammal struct {

weight int}func (m Mammal) getWeight() int {

return m.weight}func (m Mammal) setWeight(w int) {

m.weight = w}type Dog struct {

AnimalMammal

}func main() {

d := Dog{Animal{4}, Mammal{10}}fmt.Printf("A Dog has this many legs: %d oh... and weight: %d", d.numberOfLegs(), d.getWeight())

}

Page 31: Golang basics for Java developers - Part 1

Pointer receivers -bit.ly/2aKK7sipackage mainimport "fmt"type Animal struct {

legCount int}func (a Animal) numberOfLegs() int {

return a.legCount}func (a Animal) setLegs(c int) {

a.legCount = c}func (a *Animal) setLegsPtr(c int) {

a.legCount = c}type Dog struct {

Animal //anonymous field Animal}func main() {

d := Dog{Animal{4}}fmt.Println("A Dog has this many legs: ", d.numberOfLegs())d.setLegs(5)fmt.Println("A Dog has this many legs: ", d.numberOfLegs())d.setLegsPtr(6)fmt.Println("A Dog has this many legs: ", d.numberOfLegs())

}

Page 32: Golang basics for Java developers - Part 1

Arrays -bit.ly/2ahx5EAArrays has fix size and type with zero based indexing:

var integers [20]int

package main

import "fmt"

func main() {var a [2]string // std declaration a[0] = "Hello"a[1] = "Zooplus"fmt.Println(a[0], a[1])fmt.Println(a)fibonacci := [6]int{1, 1, 2, 3, 5, 7} // on-the-fly declarationfmt.Println(fibonacci)

}

Page 33: Golang basics for Java developers - Part 1

Slices - bit.ly/2ahVarPSlice is a dynamic version of array (a sort of):

var integers []int // decleration of a slice without size

package main

import "fmt"

func main() {fibonacci := [6]int{1, 1, 2, 3, 5, 7}var p []int = fibonacci[1:4]fmt.Println(p)

}

Page 34: Golang basics for Java developers - Part 1

Slices are not storing data - bit.ly/2aai1Wxpackage main

import "fmt"

func main() {names := [4]string{

"John","Paul","George","Ringo",

}fmt.Println(names)

a := names[0:2]b := names[1:3]fmt.Println(a, b)

b[0] = "XXX"fmt.Println(a, b)fmt.Println(names)

}

Page 35: Golang basics for Java developers - Part 1

Slices - boundsThere are default low and high bounds for slices. Given the following array:

var a [10]int

The following slice declarations are equivalent:

a[0:10]

a[:10]

a[0:]

a[:]

Page 36: Golang basics for Java developers - Part 1

Creating slice:

a := make([]int, 5) // len(a)=5

Creating slice with capacity:

b := make([]int, 0, 5) // len(b)=0, cap(b)=5

Appending slice:

b = append(b, 10)

Further reading: https://blog.golang.org/go-slices-usage-and-internals

Slices - create, append

Page 37: Golang basics for Java developers - Part 1

Arrays, slices - for loop as foreachIterate through an array/slice

for index, value := range arr { fmt.Println("Index:", index, "Value:", value)}Get the index only:

for index := range arr { fmt.Println("Index:", index)}

Get the values:

for _, value := range arr { fmt.Println("Value:", value)}

Page 38: Golang basics for Java developers - Part 1

Maps - declaration, initializationMaps are not initialized by default, we should use make:

package main

import "fmt"

var m map[string]string

func main() {m = make(map[string]string)m["Zooplus"] = "Gut"m["Bitiba"] = "Gut"m["Fressnapf"] = "Falsch"fmt.Println(m["Zooplus"])

}

Page 39: Golang basics for Java developers - Part 1

Maps - Mutating mapsm[key] = item // upsert

item = m[key] // retrieve

delete (m, key) // guess….

_, ok = m[key] // ok == true if key exists, map can store/return nil

Maps are not thread safe!!!

Page 40: Golang basics for Java developers - Part 1

Maps - for loop as foreachIterate through a map:

for key, value := range m { fmt.Println("Key:", key, "Value:", value)}Get the keys:

for key := range m { fmt.Println("Key:", key)}

Get the values:

for _, value := range m { fmt.Println("Value:", value)}

Page 41: Golang basics for Java developers - Part 1

Overview

Basic syntax and structure

Datatypes

Flow control

Functions, interfaces

Concurrency

Java vs. Go

Page 42: Golang basics for Java developers - Part 1

The one and only: for loop// normal loopsum := 0// init-condition-postfor i := 0; i < 10; i++ {

sum += i}fmt.Println(sum)

// partial loopsum := 0// init and post are optionalfor ; sum < 10; {

sum += sum}

// “while” loopsum := 1// init and post are optionalfor sum < 1000 {

sum += sum}fmt.Println(sum)

// infinite loopfor {

}

Page 43: Golang basics for Java developers - Part 1

func GetProject(req *restful.Request, resp *restful.Response) {resp.Header().Set("Pragma", "no-cache")//pId := req.PathParameter("projectId")

if project, ok := projects.GetProjectByIdOrName(pId); ok {

ReturnJSON(resp, http.StatusOK, project)}ReturnMessage(resp, http.StatusNotFound, "Project not

found!")}

If-then-elseexistingPipeline, ok := nameSpace.Pipelines[newPipeline.Name]if ok {

log.Debug("Entry exists!")} else {

nameSpace.Pipelines[newPipeline.Name] = existingPipelinelog.Debug("New entry stored")

}

?

Page 44: Golang basics for Java developers - Part 1

SwitchSwitch in Golang is a bit different from Java:

No automatic fallthrough, no need to put break at the end in every cases

You can delegate expression evaluation into the case block

fallthrough keyword for java-ish behavior

Multiple conditions in one case (no empty cases like in java)

Not limited to string and int

Type switch can be used for interface{} to find out the real type (instanceof)

Page 45: Golang basics for Java developers - Part 1

Switch - no fallthrough by defaultswitch c {case '&': esc = "&amp;"case '\'': esc = "&apos;"case '<': esc = "&lt;"case '>': esc = "&gt;"case '"': esc = "&quot;"default: panic("unrecognized escape character")}

Page 46: Golang basics for Java developers - Part 1

Switch - strings are welcomeswitch syscall.OS {case "windows":...case "plan9":...default:...}

Page 47: Golang basics for Java developers - Part 1

Switch - (multiple)expression(s) in casesswitch { case '0' <= c && c <= '9': return c - '0' case 'a' <= c && c <= 'f': return c - 'a' + 10 case 'A' <= c && c <= 'F': return c - 'A' + 10}

switch chars[code].category { case "de", "uk", "fr", "sp", "nl": return true }

Page 48: Golang basics for Java developers - Part 1

Switch - Type switchswitch v.(type) { case int: return "int" case string: return "string" default: return "unknown" }

Page 49: Golang basics for Java developers - Part 1

Switch - you can break itswitch argv[0] {case "echo": fmt.Print(argv[1:]...)case "cat": if len(argv) <= 1 { fmt.Println("Usage: cat <filename>") break } PrintFile(argv[1])default: fmt.Println("Unknown command; try 'echo' or 'cat'")}

Page 50: Golang basics for Java developers - Part 1

Switch - fallthroughswitch len(src) {default: v |= uint32(src[3]) fallthroughcase 3: v |= uint32(src[2]) << 8 fallthroughcase 2: v |= uint32(src[1]) << 16 fallthroughcase 1: v |= uint32(src[0]) << 24}

Page 51: Golang basics for Java developers - Part 1

Errors instead of exceptionsGolang has no exceptions

and of course there are no checked exceptions :)))))))

No try-catch-finally.

Error is just an interface

Functions are often returning a value and an error together.Checking this error for nil is the exception handling in Golang:

// validatepipeline, err := validateYaml(buf.Bytes())if err != nil {

errorMessage := fmt.Sprintf("Error parsing pipeline config: %s", err)log.Error(errorMessage)http.Error(w, errorMessage, http.StatusBadRequest)

} else {...}

NO CHECKED EXCEPTIONS!!!

Page 52: Golang basics for Java developers - Part 1

Deferfunc CopyFile(dstName, srcName string) (written int64, err error) { src, err := os.Open(srcName) if err != nil { return } defer src.Close() dst, err := os.Create(dstName) if err != nil { return }

defer dst.Close() defer fmt.Println(“All closed”) return io.Copy(dst, src)}

Page 53: Golang basics for Java developers - Part 1

Panic and Recover -bit.ly/2a5m0mJfunc main() {

f()fmt.Println("Returned normally from f.")

}func f() {

defer func() {if r := recover(); r != nil {

fmt.Println("Recovered in f", r)}

}()fmt.Println("Calling g.")g(0)fmt.Println("Returned normally from g.")

}func g(i int) {

if i > 3 {fmt.Println("Panicking!")panic(fmt.Sprintf("%v", i))

}defer fmt.Println("Defer in g", i)fmt.Println("Printing in g", i)g(i + 1)

}

Page 54: Golang basics for Java developers - Part 1

Overview

Basic syntax and structure

Datatypes

Flow control

Functions, interfaces

Concurrency

Java vs. Go

Page 55: Golang basics for Java developers - Part 1

Functions -bit.ly/2a5mg4Wpackage main

import "fmt"

func swap(x, y string) (string, string) { // also can use (x string, y string)return y, x

}

func main() {a, b := swap("hello", "zooplus")fmt.Println(a, b)

}

Page 56: Golang basics for Java developers - Part 1

Functions -bit.ly/2aymMe6package main

import "fmt"

func split(sum int) (x, y int) {x = sum * 4 / 9y = sum - xreturn

}

func main() {fmt.Println(split(17))

}

Page 57: Golang basics for Java developers - Part 1

InterfacesGolang has no “implements” keyword. If you implement all methods defined by the interface, then you are implemented the interface implicitly.

package mainimport "fmt"type I interface {

M()}type T struct {

S string}// This method means type T implements the interface I,// but we don't need to explicitly declare that it does so.

func (t T) M() {fmt.Println(t.S)

}func main() {

var i I = T{"hello"}i.M()

}

Page 58: Golang basics for Java developers - Part 1

The empty interface - bit.ly/2awwq3ZLike Object in Java, Golang has the interface{} as type that compatible with every value (even with primitives).

So it can hold any value. You need type assertion to find out what is it:

package mainimport "fmt"func main() {

var i interface{} = "hello"s := i.(string)fmt.Println(s)s, ok := i.(string)fmt.Println(s, ok)f, ok := i.(float64)fmt.Println(f, ok)f = i.(float64) // panicfmt.Println(f)

}

Page 59: Golang basics for Java developers - Part 1

Reflection“In computer science, reflection is the ability of a computer program to examine and modify its own structure and behavior (specifically the values, meta-data, properties and functions) at runtime.” /Wikipedia/

Golang has a reflection package to inspect structs, interfaces or methods runtime like in Java and also you can change the values of the fields.

What you’ll miss is some bytecode manipulation and proxy generation. Mockito like framework is not possible in Golang.

See more: http://blog.ralch.com/tutorial/golang-reflection/

Page 60: Golang basics for Java developers - Part 1

Overview

Basic syntax and structure

Datatypes

Flow control

Functions, interfaces

Concurrency

Java vs. Go

Page 61: Golang basics for Java developers - Part 1

Similarities with JavaGoroutine = Thread

Locks (R, RW)

Atomic package thread safe variable handling

Waitgroup = Join

Page 62: Golang basics for Java developers - Part 1

Differences from JavaGoroutine is lightweight, but not reusable

No Threadlocal or Executorservice in Golang

Golang has no thread safe map implementation by default (https://github.com/streamrail/concurrent-map)

Golang is a pass-by-value language

Golang uses channels to communicate between threads

Golang unsafe package is more limited

To summarize: Java originally built-on the shared memory concept, but the Golang is focusing on the communication with channels

Page 63: Golang basics for Java developers - Part 1

Channelsch := make(chan int) // single item channelv:= 5ch <- v // Send v to channel ch.v := <-ch // Receive from ch, and // assign value to v.

ch := make(chan int,100) // buffered channelv:= 5ch <- v // Send v to channel ch.v := <-ch // Receive from ch, and // assign value to v.

Page 64: Golang basics for Java developers - Part 1

Looping on a channelpackage mainimport (

"fmt")func fibonacci(n int, c chan int) {

x, y := 0, 1for i := 0; i < n; i++ {

c <- xx, y = y, x+y

}

close(c)}func main() {

c := make(chan int, 10)go fibonacci(cap(c), c)for i := range c {

fmt.Println(i)}

}

Page 65: Golang basics for Java developers - Part 1

Overview

Basic syntax and structure

Datatypes

Flow control

Functions, interfaces

Concurrency

Java vs. Go

Page 66: Golang basics for Java developers - Part 1

Go and Java common pointsC like (braces)

Garbage collector

Memory safety (nil/null references, runtime bounds checks)

Statically typed

Variables initialized by default(zero/nil/false)

Methods, Interfaces

Type assertions (instanceof)

Reflection

Page 67: Golang basics for Java developers - Part 1

Go and Java differencesNative code without VM + statically linked binaries

Control over memory layout

Function values and lexical closures

Built-in strings (UTF-8)

Built-in generic maps and arrays/slices

Built-in concurrency

Page 68: Golang basics for Java developers - Part 1

Go missing parts (by intention…)No inheritance

No constructors

No classes

No implements

No final

No exceptions

No annotations

No generics

Page 69: Golang basics for Java developers - Part 1

!!! Spoiler !!!

Page 70: Golang basics for Java developers - Part 1

A restful API in GolangBuilt with Makefile

Dockerized

Documented with Swagger

Tested with Cucumber

Page 71: Golang basics for Java developers - Part 1

Good to know...

Page 72: Golang basics for Java developers - Part 1

Next stepsGo by example (https://gobyexample.com)

Tutorial (https://tour.golang.org/welcome/1)

Effective go (https://golang.org/doc/effective_go.html)

Awesome Go: https://go.libhunt.com/

Page 73: Golang basics for Java developers - Part 1

Recommended frameworksGorilla: http://www.gorillatoolkit.org/ OR https://github.com/emicklei/go-restful (with Swagger)

BDD: https://github.com/DATA-DOG/godog

Configuration: https://github.com/spf13/viper

Logging: https://github.com/Sirupsen/logrus

CLI writing: https://github.com/spf13/cobra

Microservices: https://gokit.io/

Page 74: Golang basics for Java developers - Part 1

Thank you!