Introduction to Go

71
Go 장재휴 1

Transcript of Introduction to Go

Page 1: Introduction to Go

Go장재휴

1

Page 2: Introduction to Go

Agenda1. Introduction

2. OOP in Go

3. Concurrency in Go

4. Real world Go

2

Page 3: Introduction to Go

Simple can be harder than complex

3

Page 4: Introduction to Go

1 Introduction

4

Page 5: Introduction to Go

Go is...

simplicity&

pragmatism5

Page 6: Introduction to Go

얼마나?

6

Page 7: Introduction to Go

• C#: 79

• PHP: 65

• Java: 50

• Ruby: 41

• C: 37

• Javascript: 34

• Python: 29

• Go: 257

Page 8: Introduction to Go

• C#(4.0) https://msdn.microsoft.com/en-us/library/x53a06bb(v=vs.140).aspx

• PHP(5.6.12) http://php.net/manual/en/reserved.keywords.php

• Java(SE 8) http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.9

• Ruby(2.2.2) http://ruby-doc.org/core-2.2.2/doc/keywords_rdoc.html

• C(ANSI C) https://en.wikipedia.org/wiki/Csyntax#Reservedkeywords

• Javascript(ECMAScript 6) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords

• Python(2.3.5) http://docs.python.org/release/2.3.5/ref/keywords.html

• Go(1.5) https://golang.org/ref/spec#Keywords

8

Page 9: Introduction to Go

• Java: 780

• Scala: 191

• Go: 51

9

Page 10: Introduction to Go

없다• ❌ while

• ❌ ++i ⭕ i++

• ❌ sum += i++

• ❌ enum

• ❌ class

• ❌ inheritance

• ❌ generic

• ❌ exception

10

Page 11: Introduction to Go

있다• Pointer ❗

• Duck typing ❗

• Mandatory ❗

• Code organization

• Formatting

• Indentation

• Convention11

Page 12: Introduction to Go

Readability !

12

Page 13: Introduction to Go

Static vs. Dynamic

13

Page 14: Introduction to Go

Static + Dynamic !

14

Page 15: Introduction to Go

!!

15

Page 16: Introduction to Go

2 OOP in Go

16

Page 17: Introduction to Go

What is "Object Oriented"A language is usually considered object-based if it includes the basic capabilities for an object: identity, properties, and attributesA language is considered object-oriented if it is object-based and also has the capability of polymorphism and inheritance— wikipedia

17

Page 18: Introduction to Go

Is Go Object-based Language?

18

Page 19: Introduction to Go

What is an "Object"An object is an abstract data type that has state(data) and behavior(code)— wikipedia

19

Page 20: Introduction to Go

Object in Go

// Type Declarationtype Item struct { name string price float64 quantity int}

// Method Declarationfunc (t Item) Cost() float64 { return t.price * float64(t.quantity)}

// In Actionfunc main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} fmt.Println("cost: ", shirt.Cost())}

20

Page 21: Introduction to Go

Object in Go

// Type Declarationtype Items []Item

// Method Declarationfunc (ts Items) Cost() float64 { var c float64 for _, t := range ts { c += t.Cost() } return c}

// In Actionfunc main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} items := Items{shirt, shoes}

fmt.Println("cost of shirt: ", shirt.Cost()) fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("total cost: ", items.Cost())}

21

Page 22: Introduction to Go

Object in Go

type quantity int

func (q quantity) greaterThan(i int) bool { return int(q) > i }

func (q *quantity) increment() { *q++ }

func (q *quantity) decrement() { *q-- }

func main() { q := quantity(3) q.increment() fmt.Printf("Is q(%d) greater than %d? %t \n", q, 3, q.greaterThan(3)) q.decrement() fmt.Printf("Is q(%d) greater than %d? %t \n", q, 3, q.greaterThan(3))}

22

Page 23: Introduction to Go

Go is Object-based!

23

Page 24: Introduction to Go

Is GoObject-oriented

Language?

24

Page 25: Introduction to Go

What is "Inheritance"Provides reuse of existing objectsClasses are created in hierarchiesInheritance passes knowledge down!— wikipedia

25

Page 26: Introduction to Go

Inheritance is not good!You should avoid implementation inheritance whenever possible.— James Gosling

26

Page 27: Introduction to Go

Go's approach• Go avoided inheritance

• Go strictly follows the Composition over inheritance principle

27

Page 28: Introduction to Go

What is Composition• Provides reuse of Objects

• One object is declared by containing other objects

• Composition pulls knowledge into another

28

Page 29: Introduction to Go

29

Page 30: Introduction to Go

Composition in Go

// Type Declarationtype Item struct { name string price float64 quantity int}

type DiscountItem struct { Item discountRate float64}

// In Actionfunc main() { shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} eventShoes := DiscountItem{ Item: Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, discountRate: 10.00, }

fmt.Println("shoes: ", shoes) fmt.Println("eventShoes: ", eventShoes)}

30

Page 31: Introduction to Go

Call Method of Embedded Type

type DiscountItem struct { Item discountRate float64}

// Method Declarationfunc (t Item) Cost() float64 { return t.price * float64(t.quantity)}

// In Actionfunc main() { shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} eventShoes := DiscountItem{ Item: Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, discountRate: 10.00, }

fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("cost of eventShoes: ", eventShoes.Cost())}

31

Page 32: Introduction to Go

Method Overriding

// Method Declarationfunc (t Item) Cost() float64 { return t.price * float64(t.quantity)}

func (t DiscountItem) Cost() float64 { return t.Item.Cost() * (1.0 - t.discountRate/100)}

// In Actionfunc main() { shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} eventShoes := DiscountItem{ Item: Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, discountRate: 10.00, }

fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("cost of eventShoes: ", eventShoes.Cost())}

32

Page 33: Introduction to Go

// Type Declaration (embedded field)type Items []Item

type Order struct { Items taxRate float64}

// Overriding Methodsfunc (o Order) Cost() float64 { return o.Items.Cost() * (1.0 + o.taxRate/100)}

func main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} items := Items{shirt, shoes} order := Order{Items: items, taxRate: 10.00}

fmt.Println("cost of shirt: ", shirt.Cost()) fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("total cost: ", items.Cost()) fmt.Println("total cost(included Tax): ", order.Cost())}

33

Page 34: Introduction to Go

func main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} eventShoes := DiscountItem{ Item: Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, discountRate: 10.00, } items := Items{shirt, shoes, eventShoes} order := Order{Items: items, taxRate: 10.00}

fmt.Println("cost of shirt: ", shirt.Cost()) fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("cost of eventShoes: ", eventShoes.Cost()) fmt.Println("total cost: ", items.Cost()) fmt.Println("total cost(included Tax): ", order.Cost())}

34

Page 35: Introduction to Go

Polymorphism

35

Page 36: Introduction to Go

What is "Polymorphism"The provision of a single interface to entities of different typesVia Generics, Overloading and/or Subtyping— wikipedia

36

Page 37: Introduction to Go

Go’s approach• Go avoided subtyping & overloading

• Go does not provide Generics

• Polymorphism via interfaces

37

Page 38: Introduction to Go

Interfaces in Go• Interface is just set of methods

• Interface define behavior (duck typing)

If something can do this, then it can be used here.

38

Page 39: Introduction to Go

39

Page 40: Introduction to Go

Interfaces in Gotype Rental struct { name string feePerDay float64 period int}

func (r Rental) Cost() float64 { return r.feePerDay * float64(r.period)}

40

Page 41: Introduction to Go

Interfaces in Gotype Coster interface { Cost() float64}

func DisplayCost(c Coster) { fmt.Println("cost: ", c.Cost())}

func main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} video := Rental{"Interstellar", 1000, 3}

fmt.Printf("[%s] ", shirt.name) DisplayCost(shirt) fmt.Printf("[%s] ", video.name) DisplayCost(video)}

41

Page 42: Introduction to Go

// Itemstype Items []Coster

func main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} video := Rental{"Interstellar", 1000, 3, Days} eventShoes := DiscountItem{ Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, 10.00, } items := Items{shirt, video, eventShoes} order := Order{Items: items, taxRate: 10.00}

DisplayCost(shirt) DisplayCost(video) DisplayCost(eventShoes) DisplayCost(items) DisplayCost(order)}

42

Page 43: Introduction to Go

The Power of Interface• Writer interface in standard "io" packagetype Writer interface { Write(p []byte) (n int, err os.Error)}

• Fprintln function in standard "fmt" packagefunc Fprintln(w io.Writer, a ...interface{}) (n int, err error)

43

Page 44: Introduction to Go

The Power of Interface• In handle function, just write to io.Writer object

func handle(w io.Writer, msg string) { fmt.Fprintln(w, msg)}

• os.Stdout can be used for io.Writer.

func main() { msg := []string{"hello", "world", "this", "is", "an", "example", "of", "io.Writer"}

for _, s := range msg { time.Sleep(100 * time.Millisecond) handle(os.Stdout, s) }}

44

Page 45: Introduction to Go

The Power of Interfacefunc handle(w io.Writer, msg string) { fmt.Fprintln(w, msg)}

• The http.ResponseWriter can be used for io.Writer.

func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { handle(w, r.URL.Path[1:]) })

fmt.Println("start listening on port 4000") http.ListenAndServe(":4000", nil)}

45

Page 46: Introduction to Go

Go is object-oriented!• Go is object-based

• Code reuse via Composition

• Polymorphism via interface

46

Page 47: Introduction to Go

3 Concurrency in Go

47

Page 48: Introduction to Go

Go's Concurrency is

Easy to understand.Easy to use.You don't need to be an expert!

48

Page 49: Introduction to Go

Go's approach• In UNIX: processes connected by pipes

find ~/go/src | grep _test.go$ | xargs wc -l

• In Go: goroutines connected by channels

49

Page 50: Introduction to Go

Goroutine isindependently executing function.

go f()go f(x, y, ...)

• It's not a thread

• Very lightweight

• A goroutine has its own stack

• A goroutine runs concurrently50

Page 51: Introduction to Go

51

Page 52: Introduction to Go

Goroutine examplefunc main() { go long() go short() time.Sleep(3 * time.Second) // 3초 대기 fmt.Println("main 함수 종료", time.Now())}func long() { fmt.Println("long 함수 시작", time.Now()) time.Sleep(2500 * time.Millisecond) // 2.5초 대기 fmt.Println("long 함수 종료", time.Now())}

func short() { fmt.Println("short 함수 시작", time.Now()) time.Sleep(2000 * time.Millisecond) // 2초 대기 fmt.Println("short 함수 종료", time.Now())}

52

Page 53: Introduction to Go

Channel

53

Page 54: Introduction to Go

Channel-based communication• Define

var ch chan string // definevar ch1 chan<- string // send onlyvar ch2 <-chan string // receive only

• Create

ch = make(chan string) // create

• Use

ch <- "msg" // send value on channelm := <-ch // receive value from channel

54

Page 55: Introduction to Go

Communicating goroutinesfunc main() { done := make(chan bool) go long(done) go short(done) <-done <-done fmt.Println("main 함수 종료", time.Now())}func long(done chan bool) { fmt.Println("long 함수 시작", time.Now()) time.Sleep(2500 * time.Millisecond) // 2.5초 대기 fmt.Println("long 함수 종료", time.Now()) done <- true}func short(done chan bool) { fmt.Println("short 함수 시작", time.Now()) time.Sleep(2000 * time.Millisecond) // 2초 대기 fmt.Println("short 함수 종료", time.Now()) done <- true}

55

Page 56: Introduction to Go

Go's Concurrency is

• Goroutines give the efficiency of an asynchronous model.

• But you can write code in a synchronous style.

Don’t communicate by sharing memory . Instead, share memory by communicating.

56

Page 57: Introduction to Go

4 Real world Go

57

Page 58: Introduction to Go

Messaging

58

Page 59: Introduction to Go

59

Page 60: Introduction to Go

Go60

Page 61: Introduction to Go

A Tour of Go

⌘+C ⌘+V = ✌

61

Page 62: Introduction to Go

Measure First• Ruby version

• Go version

62

Page 63: Introduction to Go

Excuting next job while waiting

63

Page 64: Introduction to Go

Run synchronouslyerr1 := msg.save()

c, err2 := msg.fetchChannel()msg.setChannel(c)

u, err3 := msg.fetchUser()msg.setUser(u)

if err1 != nil || err2 != nil || err3 != nil { /* ... */}

64

Page 65: Introduction to Go

Run concurrentlyerrc := make(chan error)

go func() { err := msg.save() errc <- err}()

go func() { c, err := msg.fetchChannel() msg.setChannel(c) errc <- err}()

go func() { u, err := msg.fetchUser() msg.setUser(u) errc <- err}()

err1, err2, err3 := <-errc, <-errc, <- errcif err1 != nil || err2 != nil || err3 != nil { /* ... */ }

65

Page 66: Introduction to Go

Result(Concurrency)• baseline

• concurrency

66

Page 67: Introduction to Go

Caching• RDBMS can be slow

• Using Redis is good, but fault tolerance is too hard.

• Solution: Timeout waiting

67

Page 68: Introduction to Go

Caching with control variancefunc fetchUser(id string) (*User, error) { var u *User var err error

done := make(chan *User) go func() { u, _ := findFromRedis(id) done <- u }()

select { case u = <-done: case <-time.After(REDIS_TIMEOUT * time.Millisecond): }

if u == nil { u, err = findFromSql(id) if err != nil { return nil, err } saveToRedis(u) } return u, nil}

68

Page 69: Introduction to Go

Result(Caching)• concurrency

• caching

69

Page 70: Introduction to Go

Before and After• Ruby version

• Go version

70

Page 71: Introduction to Go

Conclusion

71