fabian wenzelmann august 1, 2017€¦ · 2 docker-compose exec golang /bin/bash f. wenzelmann...

126
Introduction to the Go Programming Language Fabian Wenzelmann August 1, 2017 F. Wenzelmann Introduction to Go August 1, 2017 1 / 126

Upload: others

Post on 18-Aug-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Introduction to the Go Programming Language

Fabian Wenzelmann

August 1, 2017

F. Wenzelmann Introduction to Go August 1, 2017 1 / 126

Page 2: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Why Go?

What is Go?

Go is a programming language developed at Google

It is free and open source, available for Linux, Windows and Apple OSX

Some buzzwords

CompiledStatically typedProvides garbage collectionFeatures concurrent programming

F. Wenzelmann Introduction to Go August 1, 2017 2 / 126

Page 3: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics

Hello World

package main

impor t (” fmt”

)

func main ( ) {fmt . P r i n t l n ( ” He l l o World ! ” )

}

Try on Go Playground: https://play.golang.org/p/F13xofYIV-

F. Wenzelmann Introduction to Go August 1, 2017 3 / 126

Page 4: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics

Installing Go I

We will do some small exercises togehter, to follow this you need toinstall Go

I recommend using Go ≥ 1.7

Follow instructions here: https://golang.org/doc/install,install from .tar

Don’t forget to set $GOPATH

git clone https://git.fabianwen.de/fabian/golangsrc inyour src directory

. . . or clone it somewhere and use docker:1 docker-compose up2 docker-compose exec golang /bin/bash

F. Wenzelmann Introduction to Go August 1, 2017 4 / 126

Page 5: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics

Installing Go II

Test your installation:go install golangsrc/examples/helloworld

Execute /go/bin/helloworld (or whatever your gopath is)

Most of the examples from the slides can be found ingolangsrc/examples

Exercise templates (most of them can’t be compiled until you do theexercise) in golangsrc/exercises

F. Wenzelmann Introduction to Go August 1, 2017 5 / 126

Page 6: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics

Toward Go 2

On July 13, 2017 Go version 2 was announced:https://blog.golang.org/toward-go2

There is a plan on how the developers will proceed

Go 2 will be compatible with Go 1 code

No fixed schedule yet

F. Wenzelmann Introduction to Go August 1, 2017 6 / 126

Page 7: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics

Defining Functions

Function definition with the func keyword

The type of a variable / function comes after the variable name /function name

You don’t use a semicolon to end a statement

f unc IntMax ( a i n t , b i n t ) i n t {i f a > b {

r e t u r n a} e l s e {

r e t u r n b}

}

Playground: https://play.golang.org/p/OeqNtD5UZv

F. Wenzelmann Introduction to Go August 1, 2017 7 / 126

Page 8: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Variables and Types

Builtin Types

Many types for ints and floats (numeric types)

int8, int16, int32, int64: architecture-independent for n-bitintegersThere are also unsigned n-bit integers like uint8, uint16, . . .float32, float64complex64, complex128

byte is an alias of uint8

bool predeclared constants true and false

string is a sequence of bytes. We’ll come to that later.

Numeric Types

When working with ints you usually work with the implementation-specifictypes int and uint which is either a 32 or 64 bit integer.

F. Wenzelmann Introduction to Go August 1, 2017 8 / 126

Page 9: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Variables and Types

Defining a Variable

There are different ways of defining a variable:

f unc main ( ) {va r i i n t = 21va r j i n tj = 42k := 84 // s h o r t a s s i gnment s ta tement

fmt . P r i n t l n ( i , j , k )}

Playground: https://play.golang.org/p/q8RMxk8Hzy

Short assignment statements can be used inside function definitions,the type in this example is int.

F. Wenzelmann Introduction to Go August 1, 2017 9 / 126

Page 10: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Variables and Types

About Types and Conversions

Go doesn’t do automatic type conversions, you have to do it explictly

int is a new type that is either int32 or int64, but it is not an aliasfor it!

va r i i n t 6 4 = 42va r j i n t = i

cannot use i (type int64) as type int in assignment

va r j i n t = i n t ( i )

An exception is byte which is really an alias for uint8

F. Wenzelmann Introduction to Go August 1, 2017 10 / 126

Page 11: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Case Distinction

If-Else and Switches I

If-Else statements don’t require parentheses, but braces are required

You can only use type bool in if statements

There is no thing like pythons elif, a switch statement is heavily usedin Go

f unc RateNumber (num i n t ) {i f num == 42 {

fmt . P r i n t l n ( ”The answer to e v e r y t h i n g ” )} e l s e i f num == 21 {

fmt . P r i n t l n ( ”Only h a l f the t r u t h ” )} e l s e {

fmt . P r i n t l n ( ”What a lame number” )}

}

F. Wenzelmann Introduction to Go August 1, 2017 11 / 126

Page 12: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Case Distinction

If-Else and Switches II

f unc RateNumber (num i n t ) {sw i t c h num {ca se 42 :

fmt . P r i n t l n ( ”The answer to e v e r y t h i n g ” )ca se 21 :

fmt . P r i n t l n ( ”Only h a l f the t r u t h ” )d e f a u l t :

fmt . P r i n t l n ( ”What a lame number” )}

}

Playground: https://play.golang.org/p/nn2N5rYL0E

F. Wenzelmann Introduction to Go August 1, 2017 12 / 126

Page 13: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Case Distinction

About the Switch Statement I

Switches work with many types, for example strings

Cases are evaluated from top to bottom and the switch stops when acase succeeds

If you want a fallthrough behaviour like in C++ use the fallthrough

keyword at the end of the case

If no variable is specified, a switch on the first case that evaluates totrue is performed

You can specifiy multiple values in one case, separated by comma

F. Wenzelmann Introduction to Go August 1, 2017 13 / 126

Page 14: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Case Distinction

About the Switch Statement II

f unc WakeUp(h i n t ) {sw i t c h {ca se h < 11 :

fmt . P r i n t l n ( ”Eeeew , tha t e a r l y ?” )ca se h > 15 :

fmt . P r i n t l n ( ”Had some fun l a s t n i g h t ?” )d e f a u l t :

fmt . P r i n t l n ( ”Seems p r e t t y normal to me . ” )}

}

Playground: https://play.golang.org/p/QbWQU0o1xp

F. Wenzelmann Introduction to Go August 1, 2017 14 / 126

Page 15: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Loops

The For Loop I

There is only one statement in Go for a loop, for

There are different variations of this statement:

f unc Pr intNumbers ( s t a r t , end i n t ) {f o r i := s t a r t ; i < end ; i++ {

fmt . P r i n t l n ( i )}

}

Playground: https://play.golang.org/p/wv6JK69ioz

F. Wenzelmann Introduction to Go August 1, 2017 15 / 126

Page 16: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Loops

The For Loop II

The init and post statements are optional

Just put the ; there and leave the commands blank

continue and break are supported

f unc F a c t o r i a l ( n u i n t ) u i n t {va r r e s u i n t = 1va r i u i n t = 1f o r ; i <= n ; i++ {

r e s ∗= i}r e t u r n r e s

}

Playground: https://play.golang.org/p/vTeZ5fuUlT

F. Wenzelmann Introduction to Go August 1, 2017 16 / 126

Page 17: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Loops

The For Loop III

If you want something like a while loop use for with just a condition:

f o r i < n {// your code he r e

}

For an infinite loop skip even that:

f o r {// your code he r e

}

F. Wenzelmann Introduction to Go August 1, 2017 17 / 126

Page 18: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Loops

Switches in a for-Loop I

Caution

Be careful that the break statement breaks a switch statement aswell as a for loop!

So using break in a switch statement inside a for loop breaks theswitch, not the for!

F. Wenzelmann Introduction to Go August 1, 2017 18 / 126

Page 19: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Loops

Switches in a for-Loop II

We want define a function that prints the first number i betweenstart and end that is divisible by num

The following code is wrong

f unc P r i n t D i v i s i b l e ( s t a r t , end , num i n t ) {f o r i := s t a r t ; i <= end ; i++ {

sw i t c h {ca se i%num == 0 :

fmt . P r i n t f ( ” F i r s t number d i v i s i b l e by %d i s %d\n” ,num , i )

b reak}

}}

Playground: https://play.golang.org/p/CcvByJbGDE

F. Wenzelmann Introduction to Go August 1, 2017 19 / 126

Page 20: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Loops

Switches in a for-Loop III

You have to create a label for breaking the loop in this case:

f unc P r i n t D i v i s i b l e ( s t a r t , end , num i n t ) {Loop :

f o r i := s t a r t ; i <= end ; i++ {sw i t c h {ca se i%num == 0 :

fmt . P r i n t f ( ” F i r s t number d i v i s i b l e by %d i s %d\n” ,num , i )

b reak Loop}

}}

Playground: https://play.golang.org/p/W2k4Uu0_Oj

F. Wenzelmann Introduction to Go August 1, 2017 20 / 126

Page 21: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Loops

Switches in a for-Loop IV

The same problem with break occurs when using a select

statement (later)

When working with switches in loops it’s usually a good idea to use alabel and use break / continue with the label

F. Wenzelmann Introduction to Go August 1, 2017 21 / 126

Page 22: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Loops

Exercise Session 1 I

Before we start the exercises: You should either copy the templatefrom the exercises directory into mysolutions

. . . or edit the template files directly, make sure to keep the directorystructure

Sample solutions are in solutions, but this spoils the fun

The exercises are not very challenging, you should just get familiarwith Go

cd into the directory containing the .go file and compile withgo build FILENAME.go

This creates an executable called FILENAME

F. Wenzelmann Introduction to Go August 1, 2017 22 / 126

Page 23: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Loops

Exercise Session 1 II

Exercise Template: exercises/prime

(a) Implement a function

I sP r ime ( n u i n t ) boo l

that tests if n is prime number

(b) In the main() function print the first 100 prime numbers

F. Wenzelmann Introduction to Go August 1, 2017 23 / 126

Page 24: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Loops

Exercise Session 1 III

Exercise Template: exercises/exp

Implement a method

Exp ( x , e p s i l o n f l o a t 6 4 ) f l o a t 6 4

That computes ex with the following sum:

ex =∞∑n=0

xn

n!

Stop when two consecutive sums differ by a value < ε where ε > 0.

F. Wenzelmann Introduction to Go August 1, 2017 24 / 126

Page 25: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Arrays

Arrays are very important, but you don’t use them very often directly- instead you use slices

An array of type T of size n is declared as var array [n]T

Note that var array [n]T and var array [m]T are different typesfor n 6= m

The elements are initialized with a default value (0 for numbers)

Access as in other languages: array[i]

Example: https://play.golang.org/p/xzPd-j2Cet

F. Wenzelmann Introduction to Go August 1, 2017 25 / 126

Page 26: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Working With Arrays

Arrays are not passed by reference, you’ll always get a copy whenpassing it to a function / assigning an existing array to a variable

Example: https://play.golang.org/p/LkYq1WdOb8

Instead of arrays you usually use a slice

F. Wenzelmann Introduction to Go August 1, 2017 26 / 126

Page 27: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Slices I

A slice describes a part of an array

A slice of type T has the signature []T and it can be created from anarray given the start and end position

Don’t pass a pointer to a slice, pass the array directly (this does notcopy the content of the underlying array)

Create a slice from an array with a[start:end]

Chaning the value s[i] = something changes the value in theunderlying array

Example: https://play.golang.org/p/Hl81CgMaRH

F. Wenzelmann Introduction to Go August 1, 2017 27 / 126

Page 28: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Slices II

You can also create a slice from an existing one and get / set anelement out of a slice using the same notation as with arrays:

va r a r r a y [ 4 ] i n ta r r a y [ 0 ] = 1a r r a y [ 1 ] = 2a r r a y [ 2 ] = 3a r r a y [ 3 ] = 4s1 := a r r a y [ 1 : 4 ]s2 := s1 [ 1 : 2 ]fmt . P r i n t l n ( s2 )fmt . P r i n t l n ( s1 [ 0 ] )fmt . P r i n t l n ( s2 [ 0 ] )

Playground: https://play.golang.org/p/23-hDNQWqC

F. Wenzelmann Introduction to Go August 1, 2017 28 / 126

Page 29: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Slices in Action

A slice can be used as you use a vector in other programminglanguages

You can append elements to a slice, if the underlying array is not bigenough a new one will be allocated

This especially means that if a slice grows bigger than its capacity youdon’t reference the same array as before!

You can determine the size of a slice with len(s)

A slice also has a capacity, which stores how much space theunderlying array has: cap(s)

Further reading: https://blog.golang.org/slices

F. Wenzelmann Introduction to Go August 1, 2017 29 / 126

Page 30: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Slice Examples I

To create an empty slice of type T you can use the make method:

s := make ( [ ] i n t , 5)

This will create a slice containing five elements (all 0)

You can also specify the a capacity (the size of the underlying array):

s := make ( [ ] i n t , 5 , 10)

The length of this slice is 5, but if you append another element thereis no need to create a new array

Example on Playground:https://play.golang.org/p/znhup7U18G

F. Wenzelmann Introduction to Go August 1, 2017 30 / 126

Page 31: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Slice Examples II

The append function appends an element to a slice and returns a newslice (remember that the array underneath can change)

You can also pass more than one element to append

s := make ( [ ] i n t , 1 , 1)s = append ( s , 1)fmt . P r i n t l n ( ” s : ” , s )s2 := s [ : ]s [ 0 ] = 21s2 = append ( s2 , 2 , 3)fmt . P r i n t l n ( ” s2 : ” , s2 )s [ 1 ] = 42fmt . P r i n t l n ( ” s a f t e r mod i f i c a t i o n o f s : ” , s )fmt . P r i n t l n ( ” s2 a f t e r mod i f i c a t i o n o f s : ” , s2 )

Try on the Playground: https://play.golang.org/p/01lVaqsbcV

F. Wenzelmann Introduction to Go August 1, 2017 31 / 126

Page 32: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Iterating Over Slices

You can iterate over a slice with for i := 0; i < len(s); i++

Or you can use the function range (more common):

f o r i , v := range s {fmt . P r i n t f ( ”Element on p o s i t i o n %d i s %v\n” , i , v )

}

An example on the Playground:https://play.golang.org/p/9UEhCRxRek

If you’re not interested in the position of an element name thevariable

There is an alternative method for creating a slice given anenumeration of its values:

s := [ ] f l o a t 6 4 {0 . 5 , 10 . 25 , 21 .75 , 42 .5}

F. Wenzelmann Introduction to Go August 1, 2017 32 / 126

Page 33: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Strings

The builtin type string is often used in the wrong way. . .

For Go a string is just a (read-only) slice of bytes

Go doesn’t care if it is encoded in ASCII, UTF-8 or something else

The notation str[k] returns the k-th byte in the string:

va r s t r s t r i n g = ” foo bar ”fmt . P r i n t l n ( s t r )fmt . P r i n t l n ( s t r [ 4 : ] )fmt . P r i n t l n ( l e n ( s t r ) )fmt . P r i n t l n ( s t r [ 1 ] )

Playground: https://play.golang.org/p/2St1WevT1_

F. Wenzelmann Introduction to Go August 1, 2017 33 / 126

Page 34: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Strings and UTF-8

strings are encoded in UTF-8:

s t r := ”e”fmt . P r i n t l n ( s t r )fmt . P r i n t l n ( l e n ( s t r ) )

Playground: https://play.golang.org/p/ArxIE6TgnZ

UTF-8 uses a different number of bytes, depending on the encodedchar (e for example requires three bytes)

So a for loop

f o r i := 0 ; i < l e n ( s t r ) ; i++ {. . .}

should not be used to iterate over each character!

F. Wenzelmann Introduction to Go August 1, 2017 34 / 126

Page 35: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

rune

Go uses a special type rune, which is an int32. This is a unicodecodepoint

The words character, codepoint etc. are used in an ambiguous way. . .

What you know as a character in other languages can be thought ofas a Go rune

Rune constants are enclosed in single quotes in Go. For example ’本’is mapped to the integer value 26412 (requires three bytes)

Further reading: https://blog.golang.org/strings

F. Wenzelmann Introduction to Go August 1, 2017 35 / 126

Page 36: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Using Strings

You can concatenate strings with +:

” He l l o ” + ”World”

We can also use the range function, this however treats strings in aspecial way!

Instead of iterating over the bytes the function decodes one UTF-8encoded rune in each iteration, the index of the loop is the startingposition of the current rune.

Note that some byte sequences are not valid UTF-8 points

The package unicode/utf8 has some useful functions for working withstrings and runes

Other useful packages:1 strings: Manipulate UTF-8 encoded strings2 strconv: Conversion from and to basic types3 regexp: Regular expressions

F. Wenzelmann Introduction to Go August 1, 2017 36 / 126

Page 37: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Strings, Arrays and Slices

Strings and Memory

It’s important to note that strings are just slices

Therefor they refer to an array somewhere in the memory

This can lead to memory problems:

For example you load a big file in memory but you’re only interested insome part of itIf you get the part you’re interested in by creating a slice or using somemethod from strings that only returns a slice of the existing string. . . the big array referenced by that slice will never be deleted by thegarbage collectionIn such cases you should make a copy, use the copy function

F. Wenzelmann Introduction to Go August 1, 2017 37 / 126

Page 38: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Advanced Function Definitions I

A function can have multiple return values (like tuples in python) andyou can define multiple variables at once

However there is no tuple type which you can use outside a functiondefinition / variable initialization (kind of sad)

A function can take an arbitrary number of arguments (of a certaintype)

Those elements are passed to the function as a slice

F. Wenzelmann Introduction to Go August 1, 2017 38 / 126

Page 39: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Advanced Function Definitions II

f unc MinMax( a i n t , e l ement s . . . i n t ) ( i n t , i n t ) {min , max := a , af o r , v a l := range e l ement s {

sw i t c h {ca se v a l < min :

min = v a lca s e v a l > max :

max = v a l}

}r e t u r n min , max

}

Playground: https://play.golang.org/p/3YZwuOYdKY

F. Wenzelmann Introduction to Go August 1, 2017 39 / 126

Page 40: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Advanced Function Definitions III

A function that accepts multiple values like elements ...int canalso be called with a slice of that type:

s := [ ] i n t {3 , 2 , 5 , 1 , −1}MinMax (1 , s . . . )

Functions can be passed as arguments to functions and functions canreturn functions. Go also supports anonymous functions and closures

F. Wenzelmann Introduction to Go August 1, 2017 40 / 126

Page 41: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Advanced Function Definitions IV

f unc Chain ( f , g func ( i n t ) i n t ) func ( i n t ) i n t {r e t u r n func ( n i n t ) i n t {

r e t u r n f ( g ( n ) )}

}

f unc main ( ) {doub l e := func ( n i n t ) i n t {

r e t u r n 2 ∗ n}addOne := func ( n i n t ) i n t {

r e t u r n n + 1}fmt . P r i n t l n ( Chain ( double , addOne ) ( 5 ) )

}

Playground: https://play.golang.org/p/6BU2tv47la

F. Wenzelmann Introduction to Go August 1, 2017 41 / 126

Page 42: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Advanced Function Definitions V

f unc F i b ona c c i ( ) func ( ) u i n t {va r a , b u i n t = 0 , 1r e t u r n func ( ) u i n t {

r e s := aa , b = b , a+br e t u r n r e s

}}

f unc main ( ) {f i b := F i b ona c c i ( )f o r i := 0 ; i < 15 ; i++ {

fmt . P r i n t l n ( f i b ( ) )}

}

Playground: https://play.golang.org/p/_VaPWQeHsV

F. Wenzelmann Introduction to Go August 1, 2017 42 / 126

Page 43: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Exercise Session 2 I

Exercise Template: exercises/mutliplyslice

Implement a function

Mu l t i p l y S l i c e ( s [ ] i n t , num i n t ) [ ] i n t

that repeats the slice s num times and returns the new slice.

s := [ ] i n t {1 , 2 , 3}fmt . P r i n t l n ( Mu l t i p l y S l i c e ( s , 3 ) )[ 1 2 3 1 2 3 1 2 3 ]

F. Wenzelmann Introduction to Go August 1, 2017 43 / 126

Page 44: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Exercise Session 2 II

Exercise Template: exercises/palindrome

Implement a function

I sPa l i n d r ome ( s s t r i n g ) boo l

that checks if s is a palindrome (ignoring cases). A palindrome is a stringthat reads the same backwards and forwards. Hint: Use []rune(s) toconvert a string to a slice of runes.

F. Wenzelmann Introduction to Go August 1, 2017 44 / 126

Page 45: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Exercise Session 2 III

Exercise Template: exercises/curry

Implement a function

Curry ( f func ( x , y i n t ) i n t , x i n t ) func ( y i n t ) i n t

s.t. Curry(f, x)(y) evaluates to f(x, y).

F. Wenzelmann Introduction to Go August 1, 2017 45 / 126

Page 46: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Maps I

The type map[KeyType]ValueType implements dictionaries

The KeyType is rather restricted, more information may be foundhere: https://blog.golang.org/go-maps-in-action

However we can use int, string, . . .

Short example:

age := map [ s t r i n g ] i n t {”Bob” : 42 ,”Susan” : 21}

age [ ”John” ] = 84fmt . P r i n t l n ( age [ ”Bob” ] )

Playground: https://play.golang.org/p/_EImqB_tg4

F. Wenzelmann Introduction to Go August 1, 2017 46 / 126

Page 47: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Maps II

Remove an entry for key (if this is not a valid key nothing willhappen):

d e l e t e ( age , ”Bob” )d e l e t e ( age , ”George ” )

F. Wenzelmann Introduction to Go August 1, 2017 47 / 126

Page 48: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Maps III

To check if a value exists you can use a two-value assignment

Otherwise you get the default value of the value type

ageSusan , hasSusan := age [ ”Susan” ]ageBob , hasBob := age [ ”Bob” ]i f hasSusan {

fmt . P r i n t l n ( ”Age o f Susan i s ” , ageSusan )} e l s e {

fmt . P r i n t l n ( ”No en t r y f o r Susan” )}i f hasBob {

fmt . P r i n t l n ( ”Age o f Bob i s ” , ageBob )} e l s e {

fmt . P r i n t l n ( ”No en t r y f o r Bob” )}

Playground: https://play.golang.org/p/lbpl7z1Oqy

F. Wenzelmann Introduction to Go August 1, 2017 48 / 126

Page 49: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Maps IV

Iterate over a map with range:

f o r key , v a l u e := range age {fmt . P r i n t l n ( ”Age o f ” , key , ” i s ” , v a l u e )

}

Playground: https://play.golang.org/p/MjUzwtFTyD

It is safe to delete keys from a map while iterating over it with range

Maps and slices are not safe to read / write concurrently fromdifferent goroutines, protect for example with a RWMutex

F. Wenzelmann Introduction to Go August 1, 2017 49 / 126

Page 50: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

Pointers

A pointer holds the memory address of a variable

For a type T there is also a type *T

The operator & generates a pointer from a variable, the operator *denotes the underlying value

f unc Swap ( a , b ∗ i n t ) {∗a , ∗b = ∗b , ∗a

}

f unc main ( ) {a := 21b := 42Swap(&a , &b )fmt . P r i n t l n ( ”a =” , a , ”b =” , b )

}

Playground: https://play.golang.org/p/076WJmx9NC

F. Wenzelmann Introduction to Go August 1, 2017 50 / 126

Page 51: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Other Basic Stuff

nil

The special type nil is what you know as null pointer from otherlanguages

Technically nil is not a type, nil can be used for different types suchas pointers, slices, maps

A slice can be nil and the slice functions will treat it as an emptyslice

So an empty slice can be defined like:

va r s [ ] i n t = n i l

Or even just

va r s [ ] i n t

F. Wenzelmann Introduction to Go August 1, 2017 51 / 126

Page 52: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Structs

Structs are used to group fields

They don’t work as classes as you know them from Java or otherlanguages!

You can define functions for your structs and they can be called withthe dot notation

F. Wenzelmann Introduction to Go August 1, 2017 52 / 126

Page 53: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Defining Structs

t ype Rec tang l e s t r u c t {Width , He ight f l o a t 6 4

}

f unc ( r ∗Rec tang l e ) Area ( ) f l o a t 6 4 {r e t u r n r . Width ∗ r . He ight

}

f unc main ( ) {r1 := Rec tang l e {5 , 10}r2 := Rec tang l e {Width : 10 , He ight : 20}fmt . P r i n t l n ( r1 . Area ( ) , r2 . Area ( ) )

}

Playground: https://play.golang.org/p/4RGXQS4uTW

F. Wenzelmann Introduction to Go August 1, 2017 53 / 126

Page 54: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Receivers

Area is a so called pointer receiver, because the Rectangle object ispassed by pointer

In contrast a value receiver does not receive a pointer but an actualstruct value

However in this case a copy of the struct is created and passed to thefunction, thus changes made to the struct are not present in theobject you called the method on

⇒ In most cases pointer receivers are the best option

Slices and Maps

Note that slices, strings and maps must not be passed as pointers. They’relightweight structs.

F. Wenzelmann Introduction to Go August 1, 2017 54 / 126

Page 55: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

”Constructors” I

There is no such thing as a constructor in Go

Instead for a struct T you usually define a method NewT(args) thatreturns a pointer to a new object:

f unc NewRectangle ( width , h e i g h t f l o a t 6 4 ) ∗Rec tang l e {r e t u r n &Rec tang l e {Width : width , He ight : h e i g h t }

}

F. Wenzelmann Introduction to Go August 1, 2017 55 / 126

Page 56: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

”Constructors” II

You may have noticed the two different ways to create a new object:

r1 := Rec tang l e {5 , 10}r2 := Rec tang l e {Width : 10 , He ight : 20}

The first one lists the elements in the order as defined in the structdefinition, the second one uses name / value pairs

The second one is much cleaner and easier to read!

I don’t know why this feature is not available for function calls...

F. Wenzelmann Introduction to Go August 1, 2017 56 / 126

Page 57: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Interfaces I

An interface is a collection of method signatures

You don’t have to specify that a struct implements an interface, Godetermines by itself if this is the case

t ype TwoDObject i n t e r f a c e {Area ( ) f l o a t 6 4Pe r ime t e r ( ) f l o a t 6 4

}

Assuming we also defined the Perimeter function, a *Rectangle

could be used as a TwoDObject

F. Wenzelmann Introduction to Go August 1, 2017 57 / 126

Page 58: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Interfaces II

t ype C i r c l e s t r u c t {Radius f l o a t 6 4

}

f unc NewCi rc l e ( r a d i u s f l o a t 6 4 ) ∗ C i r c l e {r e t u r n &C i r c l e {Radius : r a d i u s }

}

f unc ( c ∗ C i r c l e ) Area ( ) f l o a t 6 4 {r e t u r n math . Pi ∗ c . Rad ius ∗ c . Rad ius

}

f unc ( c ∗ C i r c l e ) Pe r ime t e r ( ) f l o a t 6 4 {r e t u r n 2 .0 ∗ math . Pi ∗ c . Rad ius

}

F. Wenzelmann Introduction to Go August 1, 2017 58 / 126

Page 59: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Interfaces III

f unc P r i n t I n f o ( o b j e c t TwoDObject ) {fmt . P r i n t f ( ”TwoDObject : Area = %.3 f , Pe r ime t e r = %.3 f \n” ,o b j e c t . Area ( ) , o b j e c t . Pe r ime t e r ( ) )

}

f unc main ( ) {r := NewRectangle (5 , 10)c := NewCi rc l e (5 )P r i n t I n f o ( r )P r i n t I n f o ( c )

}

Complete code on Playground:https://play.golang.org/p/3Nc6ZFa7Rw

F. Wenzelmann Introduction to Go August 1, 2017 59 / 126

Page 60: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Interfaces IV

Note that if you used a pointer receiver for type T to implementmethods for an interface the type *T implements the interface, not T

When using interfaces in functions you don’t have to pass a pointerto that interface

A variable of an interface type can have the value nil

F. Wenzelmann Introduction to Go August 1, 2017 60 / 126

Page 61: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Delegators I

You can use delegators to delegate methods to another type:

t ype A s t r u c t {}f unc ( a A) Foo ( ) {

fmt . P r i n t l n ( ”Foo on A” )a . Bar ( )

}f unc ( a A) Bar ( ) {

fmt . P r i n t l n ( ”Bar on A” )}t ype B s t r u c t {

A // d e l e g a t e methods to A}

f unc ( b B) Bar ( ) {fmt . P r i n t l n ( ”Bar on B” )

}

F. Wenzelmann Introduction to Go August 1, 2017 61 / 126

Page 62: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Delegators II

As seen before, all methods not defined in A and don’t exist in B aredelegated to the A instance

Feels like overwriting and inheritance? It isn’t! It’s the so calledcomposition pattern

B is always of type B, and not of type A!

Delegators are the same as storing an instance of that type in yourstruct and defining not implemented function and call the function onthat element

F. Wenzelmann Introduction to Go August 1, 2017 62 / 126

Page 63: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Defining an ”Alias” for a Type

You can define a new type by defining it as something like an alias forthat type

t ype I n t S e t map [ i n t ] s t r u c t {}

But it is a completely new type that only is something like an alias formap[int]interface

You can define functions explictly for this type like

f unc ( s e t I n t S e t ) I n s e r t ( v a l i n t ) {s e t [ v a l ] = s t r u c t {}{}

}

Playground: https://play.golang.org/p/TBBwzzyOpz

F. Wenzelmann Introduction to Go August 1, 2017 63 / 126

Page 64: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Consts

There are different ways to define const values, seehttps://blog.golang.org/constants for details

Usually you define something like

con s t GolangHome = ” h t t p s : // go lang . org /”cons t (

Red = ” red ”Blue = ” b l u e ”

)

Playground: https://play.golang.org/p/QNZfIqpdqe

F. Wenzelmann Introduction to Go August 1, 2017 64 / 126

Page 65: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Enum-like Types I

Go doesn’t support enum types

Instead you usually define an alias of type int

Go has an identifier iota that helps you generat sequences

Details: https://golang.org/ref/spec#Iota

We define an enumeration of all days of the week (though this isalready done in the time package)

F. Wenzelmann Introduction to Go August 1, 2017 65 / 126

Page 66: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Enum-like Types II

Define a const block and enumrate the possible values, use iota toenumerate the concrete values:

t ype Weekday i n t

con s t (Monday = Weekday ( i o t a )TuesdayWednesdayThursdayF r i d a ySaturdaySunday

)

F. Wenzelmann Introduction to Go August 1, 2017 66 / 126

Page 67: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Enum-like Types III

Define some new methods for our new type

Hint: It is always useful to define a method String() string, thisrepresentation will be used by the print functions:

f unc ( day Weekday ) S t r i n g ( ) s t r i n g {sw i t c h day {ca se Monday :

r e t u r n ”Monday”ca se Tuesday :

r e t u r n ”Tuesday”. . .

d e f a u l t :r e t u r n ”Unknown day”

}}

Actually there is a tool for generating code for such typesautomatically, stringer

F. Wenzelmann Introduction to Go August 1, 2017 67 / 126

Page 68: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Enum-like Types IV

Why the default case? In Go Weekday is just something like an aliasfor int

You can still pass literals to a function that expects such a type (likean arbitrary integer in this example)

This is however not so easy to understand, but is not needed thatmuch

You can read more about this here

Full code example on the Playground:https://play.golang.org/p/6mTq4YAGh3

F. Wenzelmann Introduction to Go August 1, 2017 68 / 126

Page 69: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Some Words About Types

Go does not support generics

There are some ”hacks”: use interface{} and then cast to theappropriate typeThis is however not very cleanBut it can be really annoying to define types like IntSet andStringSet and leads to code duplication

No (operator) overloading

You can use different types for keys in a dictionary, but the behaviouris rather confusing: See the Comparison Operators in the languagespec and the blog post about maps

F. Wenzelmann Introduction to Go August 1, 2017 69 / 126

Page 70: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Exercise Session 3 I

Exercise Template: exercises/twodobject

Implement a new type RightTriangle. Implement all the methods forTwoDObject and use a value receiver (either just save c or compute itfrom a and b).

F. Wenzelmann Introduction to Go August 1, 2017 70 / 126

Page 71: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Exercise Session 3 II

Exercise Template: exercises/bintree

Implement a type BinTree that implements a binary search tree andstores values of type int.Implement the following methods:

NewBinTree ( ) ∗BinTree

Add( elem i n t )Conta in s ( elem i n t ) boo l

F. Wenzelmann Introduction to Go August 1, 2017 71 / 126

Page 72: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Errors I

Go doesn’t use try / catch exception handling

Instead functions that could encounter errors use multiple returnvalues

Usually one of this return values is of type error:

t ype e r r o r i n t e r f a c e {E r r o r ( ) s t r i n g

}

F. Wenzelmann Introduction to Go August 1, 2017 72 / 126

Page 73: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Errors II

New errors can be created with the package errors:

e := e r r o r s .New( ”This i s an e r r o r ” )

Or if formatting is needed with the fmt package:

e := fmt . E r r o r f ( ” Index out o f bounds : %d” , i )

Or of course you can create your own error type and implement theinterface

F. Wenzelmann Introduction to Go August 1, 2017 73 / 126

Page 74: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Error Example I

f unc Pa r s e I n t ( s t r s t r i n g ) {va l , e r r := s t r c o n v . Ato i ( s t r )i f e r r != n i l {

fmt . P r i n t l n ( ” E r r o r : ” , e r r )} e l s e {

fmt . P r i n t l n ( ”Value i s ” , v a l )}

}

f unc main ( ) {Pa r s e I n t ( ”42” )Pa r s e I n t ( ”4a” )

}

Playground: https://play.golang.org/p/cyf5rwxgPr

F. Wenzelmann Introduction to Go August 1, 2017 74 / 126

Page 75: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Error Example II

There is also a special syntax for if statements that is used often in thiscontext:

f unc Pa r s e I n t ( s t r s t r i n g ) {i f va l , e r r := s t r c o n v . Ato i ( s t r ) ; e r r != n i l {

fmt . P r i n t l n ( ” E r r o r : ” , e r r )} e l s e {

fmt . P r i n t l n ( ”Value i s ” , v a l )}

}

f unc main ( ) {Pa r s e I n t ( ”42” )Pa r s e I n t ( ”4a” )

}

Playground: https://play.golang.org/p/S_4cNYYy8S

F. Wenzelmann Introduction to Go August 1, 2017 75 / 126

Page 76: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Type Assertions I

If you want to know which concrete type an interface value has youcan perform a type checkFor example you may have a type that implements error and dosomething specific if a certain type is returned

Note: This is not the normal way to do this in Go...

F. Wenzelmann Introduction to Go August 1, 2017 76 / 126

Page 77: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Type Assertions II

t ype Acce s sDen i edE r r o r s t r u c t {protectedName s t r i n g

}

f unc ( e ∗Acce s sDen i edE r r o r ) E r r o r ( ) s t r i n g {r e t u r n fmt . S p r i n t f ( ” Access to %s den i ed ” , e . protectedName )

}

f unc Eva lE r r ( e r r e r r o r ) {i f e r r == n i l {

r e t u r n}i f a c c e s sE r r , ok := e r r . ( ∗ Acce s sDen i edE r r o r ) ; ok {

fmt . P r i n t l n ( ” E v i l ! C a l l i n g 911 : ” , a c c e s s E r r )} e l s e {

fmt . P r i n t l n ( e r r )}

}

Playground: https://play.golang.org/p/QYAsDgtbGY

F. Wenzelmann Introduction to Go August 1, 2017 77 / 126

Page 78: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Type Assertions III

Can also be used in switch:

f unc P r e t t y ( any th i ng i n t e r f a c e {}) {sw i t c h v := any th i ng . ( type ) {ca se i n t :

fmt . P r i n t l n ( ” I n t : ” , v )ca s e f l o a t 6 4 , f l o a t 3 2 :

fmt . P r i n t f ( ” F l o a t : %.2 f \n” , v )ca se ∗Rec tang l e :

fmt . P r i n t f ( ” Rec tang l e : Width = %.2 f , He ight = %.2 f \n” ,v . Width , v . He ight )

d e f a u l t :fmt . P r i n t l n ( ”Something e l s e : ” , any th i ng )

}}

Playground: https://play.golang.org/p/l7tT7AWJUp

F. Wenzelmann Introduction to Go August 1, 2017 78 / 126

Page 79: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Reading a File and the defer Statement I

The defer statement is used to defer the execution of function calluntil the surrounding function returns

In the following example we show how to read a file line by line

Golang has an interface called io.Reader, see GoDoc

It has a single function:

t ype Reader i n t e r f a c e {Read ( p [ ] by te ) ( n i n t , e r r e r r o r )

}

Which reads up to len(p) bytes into p and returns the number ofbytes read

Often you don’t read directly from a Reader but use abufio.Reader or bufio.Scanner

F. Wenzelmann Introduction to Go August 1, 2017 79 / 126

Page 80: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Reading a File and the defer Statement II

f unc main ( ) {f , e r r := os . Open ( ” t e s t . t x t ” )i f e r r != n i l {

fmt . P r i n t l n ( ” E r r o r open ing f i l e : ” , e r r )os . E x i t ( 1 )

}d e f e r f . C l o s e ( )s canne r := bu f i o . NewScanner ( f )f o r s canne r . Scan ( ) {

fmt . P r i n t l n ( s canne r . Text ( ) )}i f e r r = scanne r . E r r ( ) ; e r r != n i l {

fmt . P r i n t l n ( ” E r r o r wh i l e r e a d i n g f i l e : ” , e r r )os . E x i t ( 1 )

}}

F. Wenzelmann Introduction to Go August 1, 2017 80 / 126

Page 81: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Reading a File and the defer Statement III

In the above example we first opened the file with os.Open(...)

Once sucessfully opened we defer the call to the Close function,that’s to say we wait until the surrounding function finishes and thenclose the file

We create a bufio.Scanner, by default this will scan for line breaks,but you may set a different split function

See GoDoc

Note

You can use multiple defer statements, even with the same variablename. The deferred call’s arguments are evaluated immediately. But thefunction call is not executed until the surrounding function returns!a

a https://tour.golang.org/flowcontrol/12

F. Wenzelmann Introduction to Go August 1, 2017 81 / 126

Page 82: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Basics Structs and Interfaces

Reading a File and the defer Statement IV

There is also a mechanism called panic and recover

We will not discuss it here, here’s some reading:https://blog.golang.org/defer-panic-and-recover

F. Wenzelmann Introduction to Go August 1, 2017 82 / 126

Page 83: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

What is Concurrency

Wikipedia

Concurrent computing is a form of computing in which severalcomputations are executed during overlapping time periods — concurrently— instead of sequentially (one completing before the next starts).Source: https://en.wikipedia.org/wiki/Concurrent_computing

We may think of it as many things happening simultaneously

Many languages and models today are not very good at expressingthis view

F. Wenzelmann Introduction to Go August 1, 2017 83 / 126

Page 84: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

The go Statement

Go is most popular for its mechanism for concurrent programming,it’s very easy to write concurrent programs in Go

It provides the go statement for running things concurrently

And it also has an easy way to communicate between thingshappening concurrently

Go was strongly influenced by the paper Communicating SequentialProcesses by C. A. R. Hoare, first published 1985

Electronic version: http://www.usingcsp.com/cspbook.pdf

Further reading on the Go blog:https://blog.golang.org/share-memory-by-communicating

Don’t confuse concurrency and parallelism!

F. Wenzelmann Introduction to Go August 1, 2017 84 / 126

Page 85: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Concurrency vs. Parallelism

In what follows there are some quotes from Rob Pike’s wonderfulvideo ”Concurrency Is Not Parallelism”:https://youtu.be/cN_DpYBzKso

Concurrency is a way of thinking and designing / structuring software

”The goal of concurrency is a good structure”

”(Concurrency) Is the execution of independently executing processes”

”Parallelism on the other hand is the simultaneous execution ofmultiple things, possibly related, possibly not”

”Dealing with a lot of things at once, vs doing a lot of things at once”

But often parallelism helps you because things run faster (they don’thave to) when you execute concurrent Go programs

F. Wenzelmann Introduction to Go August 1, 2017 85 / 126

Page 86: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

The go Statement - A Simple Example I

The go statement starts a new goroutine and runs it concurrently

It’s as simple as this: Use go f(args) to run something concurrent,you don’t wait for the routine to finish, you just start it and it doessomething for you

A pretty easy example:

f unc main ( ) {go func ( ) {

f o r i := 0 ; i < 10 ; i++ {fmt . P r i n t l n ( i )

}} ( )

}

Playground: https://play.golang.org/p/zepOa66Kjm

F. Wenzelmann Introduction to Go August 1, 2017 86 / 126

Page 87: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

The go Statement - A Simple Example II

If you run the program, what happens?

You’ll probably see nothing, as mentioned before a new goroutinestarts, the current goroutine will not wait for another one to finish!

Add time.Sleep() and we should see something

f unc main ( ) {go func ( ) {

f o r i := 0 ; i < 10 ; i++ {fmt . P r i n t l n ( i )

}} ( )t ime . S l e ep (2 ∗ t ime . Second )

}

Playground: https://play.golang.org/p/DmddLXe30Y

F. Wenzelmann Introduction to Go August 1, 2017 87 / 126

Page 88: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

The go Statement - A Simple Example III

Of course using time.Sleep is no proper way to wait for a goroutineto finish

We need a way to communicate

But first look at another simple example where we start multiplegoroutines at once

F. Wenzelmann Introduction to Go August 1, 2017 88 / 126

Page 89: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

The go Statement - A Simple Example IV

package main

impor t (” fmt”” t ime ”

)

func main ( ) {f o r i := 0 ; i < 10 ; i++ {

go func ( v a l i n t ) {fmt . P r i n t l n ( v a l )

}( i )}t ime . S l e ep (2 ∗ t ime . Second )

}

Let’s try it local, not in the Playground

F. Wenzelmann Introduction to Go August 1, 2017 89 / 126

Page 90: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

The go Statement - A Simple Example V

You don’t know in which order the goroutines are executed, so youget a more or less random sequence of outputs

You can think of a goroutine as a lightweight thread, but it is not athread as in other programming languages!

Go will internally take care of everything, starting multiple threads onyour OS for example

goroutines are cheap. Of course they prodocue some overhead, butstarting them is not very expensive. You can start even tens ofthousands of such goroutines

F. Wenzelmann Introduction to Go August 1, 2017 90 / 126

Page 91: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

The go Statement - A Simple Example VI

Why did we pass i as an argument to the function we started as agoroutine?

If you don’t pass an argument the functions uses i from the closure,but this closure is the same for all goroutines!

This is a common mistake, you should always pass an argument tofunctions you start in a different goroutine inside a loop

F. Wenzelmann Introduction to Go August 1, 2017 91 / 126

Page 92: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Introduction to Channels

The most basic type for communicating between different goroutinesare channels

Think of them as conduits or assembly belts

You can put an element of a certain type on the channel and receivean element from a channel

They’re safe for concurrent use, so many goroutines may write andread to / from a channel

Go principle

Do not communicate by sharing memory; instead, share memory bycommunicating.

F. Wenzelmann Introduction to Go August 1, 2017 92 / 126

Page 93: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Unbuffered Channels I

Create an (unbuffered) channel with make:

c := make ( chan i n t )

This creates a channel in which you can write integer values

For writing and receiving values there is the operator <-

Write to channel:

ch <−1

Read from channel:

v := <−ch

F. Wenzelmann Introduction to Go August 1, 2017 93 / 126

Page 94: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Unbuffered Channels II

f unc main ( ) {ch := make ( chan i n t )go func ( ) {

ch <− 1} ( )v := <−chfmt . P r i n t l n ( v )

}

Playground: https://play.golang.org/p/M0zDjeGpvC

Why is the write operation in a goroutine? Otherwise you get an errorlikefatal error: all goroutines are asleep - deadlock!

This is because channels block

F. Wenzelmann Introduction to Go August 1, 2017 94 / 126

Page 95: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Unbuffered Channels III

The write operation blocks until the value is received by a read tothat channel

The read operation blocks until it reads a value from the channel

This way you can synchronize goroutines

I.e. they have to wait for each other to finish

That leads to a simple pattern in Go: One goroutine waits for a readand one goroutine writes to that channel once it’s finished

F. Wenzelmann Introduction to Go August 1, 2017 95 / 126

Page 96: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Unbuffered Channels IV

f unc main ( ) {done := make ( chan boo l )// s t a r t a go r o u t i n ego func ( ) {

f o r i := 0 ; i < 10 ; i++ {fmt . P r i n t l n ( i )

}// once done w r i t e to channe ldone <− t r u e

} ( )// wa i t u n t i l g o r o u t i n e i s done<−done

}

Playground: https://play.golang.org/p/OJrWRT_cxN

F. Wenzelmann Introduction to Go August 1, 2017 96 / 126

Page 97: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Unbuffered Channels V

After we start the goroutine we read from a channel - so the maingoroutine blocks until a value on the channel appears

The gouroutine first does some stuff and then informs the channelthat it’s done

Let’s look at a more complex example

F. Wenzelmann Introduction to Go August 1, 2017 97 / 126

Page 98: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Computing the Minimum from a Slice of Ints I

We want to compute the minimum from a slice of int values

We will make some simplification and assume that the slice containssome elements

Sequential approach:

f unc S l i c eM in ( s [ ] i n t ) i n t {min := s [ 0 ]f o r , v := range s [ 1 : ] {

i f v < min {min = v

}}r e t u r n min

}

F. Wenzelmann Introduction to Go August 1, 2017 98 / 126

Page 99: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Computing the Minimum from a Slice of Ints II

Why don’t we cut the slice into smaller pieces and run the methodconcurrent for all pieces?

Use a channel to communicate the result of the concurrent methods

F. Wenzelmann Introduction to Go August 1, 2017 99 / 126

Page 100: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Computing the Minimum from a Slice of Ints III

f unc main ( ) {s := . . .n := l e n ( s )ch := make ( chan i n t )// s t a r t to go r o u t i n e s t ha t w r i t e the r e s u l t to chgo func ( ) {

ch <− S l i c eM in ( s [ : n / 2 ] )}()go func ( ) {

ch <− S l i c eM in ( s [ n / 2 : ] )}()r e s 1 := <−chr e s 2 := <−chi f r e s 1 < r e s 2 {

fmt . P r i n t l n ( ” Sma l l e s t v a l u e : ” , r e s 1 )} e l s e {

fmt . P r i n t l n ( ” Sma l l e s t v a l u e : ” , r e s 2 )}

}

Playground: https://play.golang.org/p/IZppTcZ32E

F. Wenzelmann Introduction to Go August 1, 2017 100 / 126

Page 101: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Does Parallelism Help?

In the above example we have the hope that our concurrent approachhelps to improve the execution time due to parallelism

Another question: Why only use two pieces? Why not split into evenmore?

Parallelism

Parallelism may help to improve your runtime, but this does not mean thata concurrent approach is always faster! Gos aim is to provide clearstructured code via concurrency, not to improve your runtime usingparallelism, but often enough this is the case!

F. Wenzelmann Introduction to Go August 1, 2017 101 / 126

Page 102: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Buffered Channels

Until now we’ve only seen unbuffered channels

Provide the buffer size as the second argument to make to create anunbuffered channel

ch := make ( chan i n t , 10)

Sends block only when the buffer is full, reads when the channel isempty

Example: Coordinate n workers that work concurrently

F. Wenzelmann Introduction to Go August 1, 2017 102 / 126

Page 103: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

range and Closing Channels I

If it is unkown how many arguments you have to read from a channel,you can use range ch to iterate over all its values

This reads until the channel gets closed by close(ch)

Example: Read values from a search of unkown size

You can also close a channel and still retrieve the remaining results

F. Wenzelmann Introduction to Go August 1, 2017 103 / 126

Page 104: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

range and Closing Channels II

f unc main ( ) {ch := make ( chan i n t )go func ( ) {

f o r i := 0 ; i < 10 ; i++ {ch <− i

}c l o s e ( ch )

} ( )f o r v a l := range ch {

fmt . P r i n t l n ( v a l )}

}

Playground: https://play.golang.org/p/Q7nSmQ6dUR

F. Wenzelmann Introduction to Go August 1, 2017 104 / 126

Page 105: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Read / Write Channels

If you want to signal that a function only reads / writes to a channelyou can use the type

chan<- string for a channel were strings can be written<-chan string for a channel were strings can be read

F. Wenzelmann Introduction to Go August 1, 2017 105 / 126

Page 106: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Running Multiple goroutines I

Sometimes you need to run multiple goroutines that don’t returnanything / don’t write to a channel

In this case you can use a WaitGroup from the sync package

F. Wenzelmann Introduction to Go August 1, 2017 106 / 126

Page 107: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Running Multiple goroutines II

f unc doSomething ( ) {t ime . S l e ep ( t ime . Second ∗ 3)

}

f unc main ( ) {va r wg sync . WaitGroupwg . Add (5 )f o r i := 0 ; i < 5 ; i++ {

go func ( ) {d e f e r wg . Done ( )doSomething ( )

} ( )}wg . Wait ( )

}

Playground: https://play.golang.org/p/XQLTxy0KgR

F. Wenzelmann Introduction to Go August 1, 2017 107 / 126

Page 108: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Running Multiple goroutines III

With wg.Add(n) you add n events to wait for

After all our go routines are started you use wg.Wait(). Thisoperation blocks until the counter reaches zero

A call to wg.Done() reduces the counter by one

If you have to dynmaically Add new values make sure that the countercan’t reach zero until you call Add

This means usually: calls to Add should execute before the statementcreating the goroutine or other event to be waited for

F. Wenzelmann Introduction to Go August 1, 2017 108 / 126

Page 109: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Running Multiple goroutines IV

Make sure to always call wg.Done

defer is a good way to achieve this

Read the doc for more details

F. Wenzelmann Introduction to Go August 1, 2017 109 / 126

Page 110: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Exercise Session 4 I

Exercise Template: exercises/matrix

Implement matrix multiplication for two matrices A ∈ Rn×m andB ∈ Rm×k .In the template you’ll find an implementation that doesn’t use concurrency.Improve this implementation by starting a goroutine for each row in A andin this goroutine starts a new goroutine for each column in B.The main function creates some big matrices and compares the executiontime of both implementations.

F. Wenzelmann Introduction to Go August 1, 2017 110 / 126

Page 111: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Concurrency in Go

Exercise Session 4 II

Exercise Template: exercises/bintree

Go has no iterator interface. There are two common approaches:

1 Implement a function that writes all values in a channel

2 Implement a function that accepts a function and applies a functionto all values in the collection

Implement both approaches for your BinTree type. Both versions shoulditerate the values sorted.

I t e r a t e V a l u e s ( ch chan<− i n t )Apply ( f func ( v a l i n t ) )

Implement the following with those methods (choose one or do both)

1 Print all values

2 Build the sum of all values

F. Wenzelmann Introduction to Go August 1, 2017 111 / 126

Page 112: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Testing and Benchmarking

The package testing

The package testing provides method for testing and benchmarkingyour code

For details see the documentation here

Put your tests in a different package, i.e. create a directory tests

Create files ending in test.go

To test function X write a method TestX(t *testing.T)

To benchmark function X write a methodBenchmarkX(b *testing.B)

F. Wenzelmann Introduction to Go August 1, 2017 112 / 126

Page 113: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Testing and Benchmarking

Testing and Benchmarking Example I

f unc F a c t o r i a l ( n u i n t ) u i n t {va r r e s u i n t = 1va r i u i n t = 1f o r ; i <= n ; i++ {

r e s ∗= i}r e t u r n r e s

}

f unc F a c t o r i a l R e c ( n u i n t ) u i n t {i f n == 0 {

r e t u r n 1} e l s e {

r e t u r n n ∗ Fa c t o r i a l R e c (n−1)}

}

F. Wenzelmann Introduction to Go August 1, 2017 113 / 126

Page 114: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Testing and Benchmarking

Testing and Benchmarking Example II

f unc T e s t F a c t o r i a l ( t ∗ t e s t i n g .T) {v a l u e s := [ ] u i n t {0 , 1 , 2 , 3}r e s u l t s := [ ] u i n t {1 , 1 , 2 , 6}

f o r i := 0 ; i < l e n ( v a l u e s ) ; i++ {f := f a c t o r i a l . F a c t o r i a l ( v a l u e s [ i ] )i f f != r e s u l t s [ i ] {

t . E r r o r f ( ” Expected %d ! = %d , got %d” , v a l u e s [ i ] ,r e s u l t s [ i ] , f )

}}

}

F. Wenzelmann Introduction to Go August 1, 2017 114 / 126

Page 115: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Testing and Benchmarking

Testing and Benchmarking Example III

Change to the directory examples/factorial/tests

Run go test:

PASSok golangsrc/examples/factorial/tests 0.001s

Add a false entry in the tests and run again:

test— FAIL: TestFactorial (0.00s)factorial test.go:15: Expected 3! = 7, got 6FAILexit status 1FAIL golangsrc/examples/factorial/tests 0.001s

F. Wenzelmann Introduction to Go August 1, 2017 115 / 126

Page 116: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Testing and Benchmarking

Testing and Benchmarking Example IV

f unc BenchmarkFac to r i a l ( b ∗ t e s t i n g .B) {f o r i := 0 ; i < b .N; i++ {

f a c t o r i a l . F a c t o r i a l (20)}

}

f unc BenchmarkFacto r i a lRec ( b ∗ t e s t i n g .B) {f o r i := 0 ; i < b .N; i++ {

f a c t o r i a l . F a c t o r i a l R e c (20)}

}

F. Wenzelmann Introduction to Go August 1, 2017 116 / 126

Page 117: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Testing and Benchmarking

Testing and Benchmarking Example V

Run go test -bench=.

BenchmarkFactorial-4 200000000 9.85 ns/opBenchmarkFactorialRec-4 20000000 81.1 ns/op

F. Wenzelmann Introduction to Go August 1, 2017 117 / 126

Page 118: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Testing and Benchmarking

Further Reading

Official documentation

https://medium.com/@matryer/

5-simple-tips-and-tricks-for-writing-unit-tests-in-golang-619653f90742

https://smartystreets.com/blog/2015/02/

go-testing-part-1-vanillla

F. Wenzelmann Introduction to Go August 1, 2017 118 / 126

Page 119: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Web Programming

The Package http

The http package provides HTTP client and server implementations

Golang is designed for web programming

When writing a server each request is handled in its own goroutine

We can’t discuss everything here, but we’ll look at a small example

context is a very useful package, but not discussed here

F. Wenzelmann Introduction to Go August 1, 2017 119 / 126

Page 120: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Web Programming

Further Web Libraries

There are connectors for may database types, Go has its own SQLpackage

You require a driver for a certain database type, for example MYSQL,postgres, sqlite, . . .

Also Redis, Memcached, . . .

I haven’t found a suitable thing like Django for python

But Gorilla offers a lot of stuff

CSRFSessionsSecure Cookies. . .

More extensive example:https://golang.org/doc/articles/wiki/

F. Wenzelmann Introduction to Go August 1, 2017 120 / 126

Page 121: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Web Programming

Templates

Instead of writing your output directly to the ResponseWriter youcan use templates

This are files in which you can use variables, call functions etc.

A bit like Django templates

For more details see https://astaxie.gitbooks.io/

build-web-application-with-golang/en/07.4.html andhttps://golang.org/pkg/html/template/

F. Wenzelmann Introduction to Go August 1, 2017 121 / 126

Page 122: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Organzing Your Go Code

Where to Put Your Go Code

Usually all your Go code is in one src directory, usually in a directorygo in your home

Put your own code in a directorygithub.com/YOURACCOUNT/YOURPACKAGE

A package contains multiple source files, each file must have packageline

package PACKAGENAME

You can add subpackages, but for small project this is sufficient

Add a cmd directory and a subdirectory for each command

For example if you have an executable helloworld, addcmd/helloworld/helloworld.go

This file must have package main and a function main()

F. Wenzelmann Introduction to Go August 1, 2017 122 / 126

Page 123: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Organzing Your Go Code

Function and Struct Names

Functions, Interfaces, Structs, . . . that begin with a capital letter areexported, i.e. can be used in other packages

Everything that starts with a lowercase letter can only be used insideyour package

You should also format your Go code with gofmt helloworld.go orgofmt PACKAGE

This shows you how the could should look like, add -w to apply theformatting directly to your file

See https://blog.golang.org/go-fmt-your-code

Plugins for Go are available for popular editors like vim, Atom, . . .

F. Wenzelmann Introduction to Go August 1, 2017 123 / 126

Page 124: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Organzing Your Go Code

Installing Third Party Packages

Use go get github.com/..., for example to install the MySQLdriver: gogetgithub.com/go-sql-driver/mysql

Use go install github.com/... to also compile the main files

See https://golang.org/doc/articles/go_command.html

F. Wenzelmann Introduction to Go August 1, 2017 124 / 126

Page 125: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

Organzing Your Go Code

Documenting Your Code

Document each function / struct / interface with a comment startingwith the name:

// He l loWor ld p r i n t s ” He l l o World” to the s t anda rd outputf unc He l loWor ld ( ) {

fmt . P r i n t l n ( ” He l l o World” )}

If you upload your code to github.com your documentation can befound on godoc.org

You can also run godoc locally: godoc -http=:6060 and then visithttp://localhost:6060/pkg/

F. Wenzelmann Introduction to Go August 1, 2017 125 / 126

Page 126: Fabian Wenzelmann August 1, 2017€¦ · 2 docker-compose exec golang /bin/bash F. Wenzelmann Introduction to Go August 1, 2017 4 / 126. Basics Installing GoII Test your installation:

The End

Thanks for Listening!

Do you have any questions or feedback?

F. Wenzelmann Introduction to Go August 1, 2017 126 / 126