2. ● Created by Google for Google scale problems
● First class concurrency support
● Easy to learn, easy to use
● Good performance by default
● C++ too hard, Python too slow, few enjoyed Java
Background
3. ● Strong, static typed language
● Garbage Collected
● Compiles to a binary
● Easy cross compilation
What is it?
4. Saker Go inte har:
● Klasser
● Konstruktorer/destruktorer
● Ineheritance
● Exceptions
● Annotations
● Generics
● (100% bakåtkompatibelt så länge 1.X)
Core feature: simplicity
5. ● Rankar runt 15:e största språk
● Rankade 9 på Github PRs
● Enda språket topp 5 “most wanted” och “most
loved” på Stack Overflow Survey 2017
● Används av ex Dropbox, Cloudflare,
DigitalOcean, Docker, Google
Popularitet
6. // Separate init and declaration
var i int // will be set to int default (0)
i = 123
var i int = 123 // Above in one line
i := 123 // Shorthand, type inferred (int)
str := “”مرحبا // UTF-8 strings
strPtr := &str // & will create pointer to value
var anotherString string
anotherString = *strPtr // * dereferences pointer
const MEETUP_NAME = “Go West”
Types
7. // map int -> string
myMap := map[int]string{}
myMap[1] = “Go”
// Array of fixed size 3
myArray := [3]string{"Go","West", “introduction”}
myArray[1] // “West”
myArray[10] // panic!
// Non preallocated slice
var mySlice []string // len(mySlice) = 0
mySlice = append(mySlice, “hi”) // len = 1
mySlice[2] = “there” // panic!
// Pre allocated slice
myAllocatedSlice := make([]string, 10) // len 10
myAllocatedSlice[2] = “Hi” // ok!
More complex types
8. Create types
type Status string // “Fake” enum
const (
Active Status = “active”
Inactive Status = “inactive”
)
type User struct {
Username string
Status Status // instead of string
Profile Profile
}
type Profile struct {
Bio string
}
u := User{
Username: “gust1n”,
Status: Active,
Profile: Profile{
Bio: “Gopher”,
},
}
u.Status = “inactive” // wont compile
14. Concurrency: data races
func calculateTotal(total int, next int) {
total = total + next
}
func main() {
var total int
for i := 0; i < 3; i++ {
go calculateTotal(total, i)
}
fmt.Printf(“total is %d”, total)
}
15. Concurrency: use mutex?
var lock sync.Mutex
func calculateTotal(total int, next int) {
lock.Lock()
total = total + next
lock.Unlock()
}
func main() {
var total int
for i := 0; i < 3; i++ {
go calculateTotal(total, i)
}
fmt.Printf(“total is %d”, total)
}
16. Concurrency: channels
// A channel is for communicating between goroutines
intCh := make(chan int, 1)
// A channel can be written to
intCh <- 1337
// and read from (blocking)
i := <- intCh
// Think of it as a pipeline of any type
userCh := make(chan *User, 1)
// Are totally safe for concurrent access
go func() {
intCh <- 1337
}()
17. Concurrency: orchestration
func calculateNext(resCh chan int, next int) {
resCh <- next
}
func main() {
resCh := make(chan int, 1)
for i := 0; i < 3; i++ {
go calculateNext(resCh, i)
}
var total int
for i := 0; i < 3; i++ {
next := <-resCh // blocks until channel written to
total = total + next
}
fmt.Printf(“total is %d”, total)
}
18. Concurrency: orchestration cont.
respCh := make(chan int, 1)
doSomethingSlow(respCh)
// blocking
select {
case resp := <-respCh:
// do something with resp
case time.After(2 * time.Second):
// timeout, move on
}
19. Real world example
package uptime
type Response struct {
URL string
StatusCode int
Duration time.Duration
}
func Check(respCh chan Response, URL string) {
start := time.Now()
resp, _ := http.Get(URL)
respCh <- Response{
URL: URL,
StatusCode:
resp.StatusCode,
Duration: time.Since(start),
}
}
package main
import (
“fmt”
“github.com/gust1n/uptime”
)
func main() {
URLs := []string{
“https://www.golang.org”,
“https://www.rust-lang.org/”,
“http://elixir-lang.github.io/”,
}
respCh := make(chan uptime.Response, 1)
for _, URL := range URLs {
go uptime.Check(respCh, URL)
}
for i := 0; i < len(URLs); i++ {
resp := <- respCh
fmt.Printf(“%s (%d) - %sn”,
resp.URL,
resp.StatusCode,
resp.Duration.String(),
)
}
}