ݺߣ

ݺߣShare a Scribd company logo
Go? ? ???? ????
Go? ??? ?? ??? ????? ??? ??? ??? ???
DEVSISTERS ???
1
???
joonsung@devsisters.com
github.com/hodduc
2010~ | KAIST CS
| ?? ??? SPARCS
2012? | ACM-ICPC 2012 Daejeon 1st place
2013? 6? | ACM-ICPC 2013 World Final 48th place
2013~2014? | ?????
2014? 8? | ?????? ??, ??? ?? ??.
?? | Go? ??? ?? ???? ?? ?
??? ??
Go? ? ???? ???? 2
? Go????
1
3
? Go????
Go? ? ???? ????
?? ??? ??
and
4
? Go????
Go? ? ???? ????
??
???? ?? ????
Spring ????
?? ?? ????? Scalable?? ???
== MySQL ? ??? ???? ??
?? ??? ? ??? ?
C++ (quic), lua (?? ??), 
5
? Go????
Go? ? ???? ????
???
6
? Go????
Go? ? ???? ????
Type safety
7
? Go????
Go? ? ???? ????
Type safety ???? ??
8
? Go????
Go? ? ???? ????
Type safety ???? ?? IDE support
9
? Go????
Go? ? ???? ????
Type safety ???? ?? IDE support ???? ???
10
? Go????
Go? ? ???? ????
??? ????!?
11
? Go????
Go? ? ???? ????
???? ????
???
?? ??
??
12
? Go????
Go? ? ???? ????
???? ???? ?? ?? ??? ?
???
?? ??
??
?? ??
?? ??
??? ????
13
? Go????
Go? ? ???? ????
???? ???? ?? ?? ??? ? Deploy?? ????
???
?? ??
??
?? ??
?? ??
??
???
???
?? ??? ????
14
? Go????
Go? ? ???? ????
?? ????
15
? Go????
Go? ? ???? ???? 16
? Go????
Go? ? ???? ????
Go? ???? ??? ?
17
? Go????
Go? ? ???? ????
Go? ???? ??? ?
? Channel? ??? ??? Concurrency ??
18
? Go????
Go? ? ???? ????
Go? ???? ??? ?
? Channel? ??? ??? Concurrency ??
? ??? ???!
19
????? ?? ??? ?? ??? ??? ???
 ? ???? ?? ??? ???? ?? ??
 ????? ???? ?? ??? ???
? Go????
Go? ? ???? ????
Go? ???? ??? ?
? Channel? ??? ??? Concurrency ??
? ??? ???!
? ??? ?? ???? ?? ??? ??
20
? Go????
Go? ? ???? ????
Go? ???? ??? ?
? Channel? ??? ??? Concurrency ??
? ??? ???!
? ??? ?? ???? ?? ??? ??
? Interface? ???
21
?? Capn proto? protobuf? ?? serialization library??
??? ??
? Go????
Go? ? ???? ????
Go? ???? ??? ?
? Channel? ??? ??? Concurrency ??
? ??? ???!
? ??? ?? ???? ?? ??? ??
? Interface? ???
? ?? ??? ??? ?? ?? ??? ???? ??? ??
22
? Go????
Go? ? ???? ????
Go? ???? ??? ?
? Channel? ??? ??? Concurrency ??
? ??? ???!
? ??? ?? ???? ?? ??? ??
? Interface? ???
? ?? ??? ??? ?? ?? ??? ???? ??? ??
? ?? ???? ??? ???
23
? Go????
Go? ? ???? ????
????? ???
24
? Go????
Go? ? ???? ????
????? ??
? ??? Full-featured Debugger? ??
the ability to use the debugger to understand a Go program's
full environment will likely never work, and improving gdb
support is not a priority for the team.
- Rob Pike, on March 2014
???? Debugger (gdb, lldb, delve, godebug, ) ?
? ??? ???? Go ?? ??? ??? print?? ????
? Function call ? ???? ???
? Goroutine? ?? ?? ? ??? ???? ???
25
? Go????
Go? ? ???? ????
????? ??
? ??? Full-featured Debugger? ??
? ?? ??? ????? ???? ????? ??
26
? Go????
Go? ? ???? ???? 27
? Go????
Go? ? ???? ????
????? ??
? ??? Full-featured Debugger? ??
? ?? ??? ????? ???? ????? ??
? ?? ?? ??? ????
Simple Typing? ?? ??? ? ????
??? Generic? ????
Int8Contains, Int16Contains, Int32Contains, Int64Contains,
Int8Random, Int16Random, ? ???? ???? ?
28
? Go????
Go? ? ???? ????
????? ??
? ??? Full-featured Debugger? ??
? ?? ??? ????? ???? ????? ??
? ??? Generic? ????
? ??? ?? ??? ?? ?? ???
if err := (); err != nil { return err }
?? ?? ??? ???? ??? ???? ??? ??
29
??, ??, ??
2
30
Concurrent Map
??, ??, ??
Go? ? ???? ???? 31
Go? map? thread-safe ?? ??
Concurrent Map
??, ??, ??
Go? ? ???? ???? 32
type Director struct {
pidMap map[int]*Actor
}
func (d *Director) Start() (*Actor, Pid) {
pid := d.createPid()
actor := NewActor(pid)
d.pidMap[pid] = actor
return actor, pid
}
panic: runtime error: invalid memory address or nil pointer dereference
Concurrent Map
??, ??, ??
Go? ? ???? ???? 33
type Director struct {
sync.RWMutex
pidMap map[int]*Actor
}
func (d *Director) Start() (*Actor, Pid) {
pid := d.createPid()
actor := NewActor(pid)
d.Lock()
defer d.Unlock()
d.pidMap[pid] = actor
return actor, pid
}
Typed nil
??, ??, ??
Go? ? ???? ???? 34
func AssertPositive(i int) *MathError {
if i < 0 {
return &MathError{i}
}
return nil
}
func Root(i int) (int, error) {
err := AssertPositive(i)
if err != nil {
return 0, err
}
return int(math.Sqrt(float64(i))), err
}
func main() {
sqrt, err := Root(81)
if err != nil {
fmt.Println("error is not nil:", err)
} else {
fmt.Println(sqrt)
}
}
Typed nil
??, ??, ??
Go? ? ???? ???? 35
func AssertPositive(i int) *MathError {
if i < 0 {
return &MathError{i}
}
return nil
}
func Root(i int) (int, error) {
err := AssertPositive(i)
if err != nil {
return 0, err
}
return int(math.Sqrt(float64(i))), err
}
func main() {
sqrt, err := Root(81)
if err != nil {
fmt.Println("error is not nil:", err)
} else {
fmt.Println(sqrt)
}
}
Typed nil
??, ??, ??
Go? ? ???? ???? 36
func AssertPositive(i int) *MathError {
if i < 0 {
return &MathError{i}
}
return nil
}
func Root(i int) (int, error) {
err := AssertPositive(i)
if err != nil {
return 0, err
}
return int(math.Sqrt(float64(i))), err
}
func main() {
sqrt, err := Root(81)
if err != nil {
fmt.Println("error is not nil:", err)
} else {
fmt.Println(sqrt)
}
}
type: *MathError
Value: nil
type: error (interface)
Value: typed nil >.<
Error interface? ???? ?
?? nil??? type? nil? ????
Interface nil? ?? ??
Typed nil
??, ??, ??
Go? ? ???? ???? 37
func AssertPositive(i int) *MathError {
if i < 0 {
return &MathError{i}
}
return nil
}
func Root(i int) (int, error) {
err := AssertPositive(i)
if err != nil {
return 0, err
}
return int(math.Sqrt(float64(i))), nil
}
func main() {
sqrt, err := Root(81)
if err != nil {
fmt.Println("error is not nil:", err)
} else {
fmt.Println(sqrt)
}
}
Typed nil
??, ??, ??
Go? ? ???? ???? 38
func RootStr(s string) (int, error) {
i, err := strconv.Atoi(s)
if err != nil {
return 0, err
}
err = AssertPositive(i)
if err != nil {
return 0, err
}
return int(math.Sqrt(float64(i))), nil
}
func main() {
sqrt, err := RootStr("81")
if err != nil {
fmt.Println("error is not nil:", err)
} else {
fmt.Println(sqrt)
}
}
Typed nil
??, ??, ??
Go? ? ???? ???? 39
func RootStr(s string) (int, error) {
i, err := strconv.Atoi(s)
if err != nil {
return 0, err
}
err = AssertPositive(i)
if err != nil {
return 0, err
}
return int(math.Sqrt(float64(i))), nil
}
func main() {
sqrt, err := RootStr("81")
if err != nil {
fmt.Println("error is not nil:", err)
} else {
fmt.Println(sqrt)
}
}
Typed nil
??, ??, ??
Go? ? ???? ???? 40
Nil? ???? ????? nil??? ??? ??? ?
(X) if err == nil { return response, err }
(O) if err == nil { return response, nil }
Typed nil
??, ??, ??
Go? ? ???? ???? 41
Nil? ???? ????? nil??? ??? ??? ?
?? ?? ??? err ??? ??? ????? ? ?
if err := Something(); err != nil { ... }
? ??? ???? if? ??? ??? Scope? ????? ?? ??
Typed nil
??, ??, ??
Go? ? ???? ???? 42
Nil? ???? ????? nil??? ??? ??? ?
?? ?? ??? err ??? ??? ????? ? ?
??? ??? ??? ?? ??? return type? error ?????? ??? ?
??, ??, ??
Go? ? ???? ???? 43
??? ?? ???
??? ?? ???
??, ??, ??
Go? ? ???? ???? 44
//go:generate ./some_runnable_command_here.sh Copt1 --opt2=foobar
$ go generate
$ go build
$ go test
??? ?? ???
??, ??, ??
Go? ? ???? ???? 45
cat <<< "
package generated
var BaseDir = "$BASEDIR"
var Version = struct {
ServerRevision string
ProtocolRevision string
DeployDate string
}{
"$SERVER_HASH",
"$PROTOCOL_HASH",
"$DEPLOY_DATE",
}
" > generated/version.go
??? ?? ???
??, ??, ??
Go? ? ???? ???? 46
type Ints []int
func (a Ints) Val() []int
func (a Ints) Copy() Ints
func (a Ints) Cut(i int, j int)
func (a Ints) Insert(i int, x int) Ints
func (a Ints) Append(x ...int) Ints
func (a Ints) Reverse()
func (a Ints) Filter(f func(i int, value interface{}) bool) Ints
func (a Ints) Each(f func(i int, value interface{}))
func (a Ints) Map(f func(i int, value interface{}) int) Ints
Type Int32s []int32
......
Type Int64s []int64
??? ?? ???
??, ??, ??
Go? ? ???? ???? 47
? shell script? ???
? ?? ??? ??? ?? ??? ??? ?
? Go, Python ?? ??? ???????
? ??? ??? ??! ???, ???? ?? ?? ??? ?
? ? ?? ? ?
? Go? ast, parser ??? ???
? ?? ? ??? ast, parser? ??? ??? ?? ??
? ???? ??? ??
? ??? ?? ?? ? ???? ??
?? ?????
3
48
vim-go
??? ??? ??????
Go? ? ???? ???? 49
Godeps
??? ??? ??????
Go? ? ???? ???? 50
? Dependency Manager & Vendoring tool
? Copy all dependencies into Workspace
directory ( ~= virtualenv in Python )
? Fix Go version, Library version, 
{
"ImportPath": "github.com/devsisters/gb-server",
"GoVersion": "go1.4.2",
"Deps": [
{
"ImportPath": "golang.org/x/net/context",
"Rev": "0b492c5a9642fa1365f77ad20bbb259a25572507"
},
{
"ImportPath": "golang.org/x/oauth2",
"Rev": "ce5ea7da934b76b1066c527632359e2b8f65db97"
},
{
"ImportPath": "google.golang.org/api/googleapi",
"Rev": "c34364630fd76916db716b46fd3a75403b161768"
},
....
go-errors
??? ??? ??????
Go? ? ???? ????
var Crashed = errors.Errorf("oh dear")
func Crash() error {
return errors.New(Crashed)
}
if err != nil {
if errors.Is(err, crashy.Crashed) {
fmt.Println(err.(*errors.Error).ErrorStack())
} else {
panic(err)
}
}
51
GoConvey
??? ??? ??????
Go? ? ???? ????
http://goconvey.co/
52
GoConvey
??? ??? ??????
Go? ? ???? ????
http://goconvey.co/
53
GoConvey
??? ??? ??????
Go? ? ???? ????
http://goconvey.co/
54
Test function
testing/quick
??? ??? ??????
Go? ? ???? ????
func TestOddMultipleOfThree(t *testing.T) {
f := func(x int) bool {
y := OddMultipleOfThree(x)
return y%2 == 1 && y%3 == 0
}
if err := quick.Check(f, nil); err != nil {
t.Error(err)
}
}
Target function
Inject random
valid parameter
Check if target function
is working well
55
??? ??? ??????
(??) (??)
4
56
Cine
??? ??? ??????
Go? ? ???? ????
github.com/devsisters/cine
? Actor model for Go (like erlang)
? All actor is identified by unique PID
? Remote actor is treated same as local one
? Supports synchronous / asynchronous function call
Cine
Host 1 Host 2 Host 3
Actor Actor Actor Actor Actor
57
Cine
??? ??? ??????
Go? ? ???? ????
github.com/devsisters/cine
type Phonebook struct {
cine.Actor
book map[string]int
}
cine.Init("127.0.0.1:8000")
phonebook := Phonebook{cine.Actor{}, make(map[string]int)}
pid := cine.StartActor(&phonebook)
// For asynchronous call (ignore all errors)
cine.Cast(pid, nil, (*Phonebook).Add, "Jane", 1234)
// For synchronous call
ret, _ := cine.Call(pid, (*Phonebook).Lookup, "Jane")
number := ret[0].(int)
58
GoQuic
??? ??? ??????
Go? ? ???? ????
github.com/devsisters/goquic
https://www.youtube.com/watch?v=hQZ-0mXFmk8
59
??? ??? ??????
Go? ? ???? ????
QUIC vs TCP+TLS+SPDY/HTTP2
? 0-RTT support
? Multiplexing without Head-of-line blocking
? Forward error correction
? Connection Migration
60
GoQuic
??? ??? ??????
Go? ? ???? ????
github.com/devsisters/goquic
Chromium
Extract QUIC core devsisters/
libquic
Go binding w/ cgo devsisters/
goquic
devsisters.github.io/goquic
// server
goquic.ListenAndServe(":8080", 1, nil)
// client
client := &http.Client{
Transport: goquic.NewRoundTripper(false),
}
resp, err := client.Get("http://example.com/")
61
????
5
62
Q. ??? Go? ? ????? ?? ????
????
Go? ? ???? ???? 63
Q. ??? Go? ? ????? ?? ????
????
Go? ? ???? ????
A. ???? ??? ???? ?????????
????? ????? ?? ?
?, ???? ?? ???
?? ??? ??? ??? ?
64
Q. ??? ???2 ?? ????
????
Go? ? ???? ???? 65
Q. ??? ???2 ?? ????
????
Go? ? ???? ????
A. ????? (??)
66
Q. ??? Go ??? ????
????
Go? ? ???? ???? 67
Go ??? ????
joonsung@devsisters.com
?????

More Related Content

Go? ? ???? ????

  • 1. Go? ? ???? ???? Go? ??? ?? ??? ????? ??? ??? ??? ??? DEVSISTERS ??? 1
  • 2. ??? joonsung@devsisters.com github.com/hodduc 2010~ | KAIST CS | ?? ??? SPARCS 2012? | ACM-ICPC 2012 Daejeon 1st place 2013? 6? | ACM-ICPC 2013 World Final 48th place 2013~2014? | ????? 2014? 8? | ?????? ??, ??? ?? ??. ?? | Go? ??? ?? ???? ?? ? ??? ?? Go? ? ???? ???? 2
  • 4. ? Go???? Go? ? ???? ???? ?? ??? ?? and 4
  • 5. ? Go???? Go? ? ???? ???? ?? ???? ?? ???? Spring ???? ?? ?? ????? Scalable?? ??? == MySQL ? ??? ???? ?? ?? ??? ? ??? ? C++ (quic), lua (?? ??), 5
  • 6. ? Go???? Go? ? ???? ???? ??? 6
  • 7. ? Go???? Go? ? ???? ???? Type safety 7
  • 8. ? Go???? Go? ? ???? ???? Type safety ???? ?? 8
  • 9. ? Go???? Go? ? ???? ???? Type safety ???? ?? IDE support 9
  • 10. ? Go???? Go? ? ???? ???? Type safety ???? ?? IDE support ???? ??? 10
  • 11. ? Go???? Go? ? ???? ???? ??? ????!? 11
  • 12. ? Go???? Go? ? ???? ???? ???? ???? ??? ?? ?? ?? 12
  • 13. ? Go???? Go? ? ???? ???? ???? ???? ?? ?? ??? ? ??? ?? ?? ?? ?? ?? ?? ?? ??? ???? 13
  • 14. ? Go???? Go? ? ???? ???? ???? ???? ?? ?? ??? ? Deploy?? ???? ??? ?? ?? ?? ?? ?? ?? ?? ?? ??? ??? ?? ??? ???? 14
  • 15. ? Go???? Go? ? ???? ???? ?? ???? 15
  • 16. ? Go???? Go? ? ???? ???? 16
  • 17. ? Go???? Go? ? ???? ???? Go? ???? ??? ? 17
  • 18. ? Go???? Go? ? ???? ???? Go? ???? ??? ? ? Channel? ??? ??? Concurrency ?? 18
  • 19. ? Go???? Go? ? ???? ???? Go? ???? ??? ? ? Channel? ??? ??? Concurrency ?? ? ??? ???! 19 ????? ?? ??? ?? ??? ??? ??? ? ???? ?? ??? ???? ?? ?? ????? ???? ?? ??? ???
  • 20. ? Go???? Go? ? ???? ???? Go? ???? ??? ? ? Channel? ??? ??? Concurrency ?? ? ??? ???! ? ??? ?? ???? ?? ??? ?? 20
  • 21. ? Go???? Go? ? ???? ???? Go? ???? ??? ? ? Channel? ??? ??? Concurrency ?? ? ??? ???! ? ??? ?? ???? ?? ??? ?? ? Interface? ??? 21 ?? Capn proto? protobuf? ?? serialization library?? ??? ??
  • 22. ? Go???? Go? ? ???? ???? Go? ???? ??? ? ? Channel? ??? ??? Concurrency ?? ? ??? ???! ? ??? ?? ???? ?? ??? ?? ? Interface? ??? ? ?? ??? ??? ?? ?? ??? ???? ??? ?? 22
  • 23. ? Go???? Go? ? ???? ???? Go? ???? ??? ? ? Channel? ??? ??? Concurrency ?? ? ??? ???! ? ??? ?? ???? ?? ??? ?? ? Interface? ??? ? ?? ??? ??? ?? ?? ??? ???? ??? ?? ? ?? ???? ??? ??? 23
  • 24. ? Go???? Go? ? ???? ???? ????? ??? 24
  • 25. ? Go???? Go? ? ???? ???? ????? ?? ? ??? Full-featured Debugger? ?? the ability to use the debugger to understand a Go program's full environment will likely never work, and improving gdb support is not a priority for the team. - Rob Pike, on March 2014 ???? Debugger (gdb, lldb, delve, godebug, ) ? ? ??? ???? Go ?? ??? ??? print?? ???? ? Function call ? ???? ??? ? Goroutine? ?? ?? ? ??? ???? ??? 25
  • 26. ? Go???? Go? ? ???? ???? ????? ?? ? ??? Full-featured Debugger? ?? ? ?? ??? ????? ???? ????? ?? 26
  • 27. ? Go???? Go? ? ???? ???? 27
  • 28. ? Go???? Go? ? ???? ???? ????? ?? ? ??? Full-featured Debugger? ?? ? ?? ??? ????? ???? ????? ?? ? ?? ?? ??? ???? Simple Typing? ?? ??? ? ???? ??? Generic? ???? Int8Contains, Int16Contains, Int32Contains, Int64Contains, Int8Random, Int16Random, ? ???? ???? ? 28
  • 29. ? Go???? Go? ? ???? ???? ????? ?? ? ??? Full-featured Debugger? ?? ? ?? ??? ????? ???? ????? ?? ? ??? Generic? ???? ? ??? ?? ??? ?? ?? ??? if err := (); err != nil { return err } ?? ?? ??? ???? ??? ???? ??? ?? 29
  • 31. Concurrent Map ??, ??, ?? Go? ? ???? ???? 31 Go? map? thread-safe ?? ??
  • 32. Concurrent Map ??, ??, ?? Go? ? ???? ???? 32 type Director struct { pidMap map[int]*Actor } func (d *Director) Start() (*Actor, Pid) { pid := d.createPid() actor := NewActor(pid) d.pidMap[pid] = actor return actor, pid } panic: runtime error: invalid memory address or nil pointer dereference
  • 33. Concurrent Map ??, ??, ?? Go? ? ???? ???? 33 type Director struct { sync.RWMutex pidMap map[int]*Actor } func (d *Director) Start() (*Actor, Pid) { pid := d.createPid() actor := NewActor(pid) d.Lock() defer d.Unlock() d.pidMap[pid] = actor return actor, pid }
  • 34. Typed nil ??, ??, ?? Go? ? ???? ???? 34 func AssertPositive(i int) *MathError { if i < 0 { return &MathError{i} } return nil } func Root(i int) (int, error) { err := AssertPositive(i) if err != nil { return 0, err } return int(math.Sqrt(float64(i))), err } func main() { sqrt, err := Root(81) if err != nil { fmt.Println("error is not nil:", err) } else { fmt.Println(sqrt) } }
  • 35. Typed nil ??, ??, ?? Go? ? ???? ???? 35 func AssertPositive(i int) *MathError { if i < 0 { return &MathError{i} } return nil } func Root(i int) (int, error) { err := AssertPositive(i) if err != nil { return 0, err } return int(math.Sqrt(float64(i))), err } func main() { sqrt, err := Root(81) if err != nil { fmt.Println("error is not nil:", err) } else { fmt.Println(sqrt) } }
  • 36. Typed nil ??, ??, ?? Go? ? ???? ???? 36 func AssertPositive(i int) *MathError { if i < 0 { return &MathError{i} } return nil } func Root(i int) (int, error) { err := AssertPositive(i) if err != nil { return 0, err } return int(math.Sqrt(float64(i))), err } func main() { sqrt, err := Root(81) if err != nil { fmt.Println("error is not nil:", err) } else { fmt.Println(sqrt) } } type: *MathError Value: nil type: error (interface) Value: typed nil >.< Error interface? ???? ? ?? nil??? type? nil? ???? Interface nil? ?? ??
  • 37. Typed nil ??, ??, ?? Go? ? ???? ???? 37 func AssertPositive(i int) *MathError { if i < 0 { return &MathError{i} } return nil } func Root(i int) (int, error) { err := AssertPositive(i) if err != nil { return 0, err } return int(math.Sqrt(float64(i))), nil } func main() { sqrt, err := Root(81) if err != nil { fmt.Println("error is not nil:", err) } else { fmt.Println(sqrt) } }
  • 38. Typed nil ??, ??, ?? Go? ? ???? ???? 38 func RootStr(s string) (int, error) { i, err := strconv.Atoi(s) if err != nil { return 0, err } err = AssertPositive(i) if err != nil { return 0, err } return int(math.Sqrt(float64(i))), nil } func main() { sqrt, err := RootStr("81") if err != nil { fmt.Println("error is not nil:", err) } else { fmt.Println(sqrt) } }
  • 39. Typed nil ??, ??, ?? Go? ? ???? ???? 39 func RootStr(s string) (int, error) { i, err := strconv.Atoi(s) if err != nil { return 0, err } err = AssertPositive(i) if err != nil { return 0, err } return int(math.Sqrt(float64(i))), nil } func main() { sqrt, err := RootStr("81") if err != nil { fmt.Println("error is not nil:", err) } else { fmt.Println(sqrt) } }
  • 40. Typed nil ??, ??, ?? Go? ? ???? ???? 40 Nil? ???? ????? nil??? ??? ??? ? (X) if err == nil { return response, err } (O) if err == nil { return response, nil }
  • 41. Typed nil ??, ??, ?? Go? ? ???? ???? 41 Nil? ???? ????? nil??? ??? ??? ? ?? ?? ??? err ??? ??? ????? ? ? if err := Something(); err != nil { ... } ? ??? ???? if? ??? ??? Scope? ????? ?? ??
  • 42. Typed nil ??, ??, ?? Go? ? ???? ???? 42 Nil? ???? ????? nil??? ??? ??? ? ?? ?? ??? err ??? ??? ????? ? ? ??? ??? ??? ?? ??? return type? error ?????? ??? ?
  • 43. ??, ??, ?? Go? ? ???? ???? 43 ??? ?? ???
  • 44. ??? ?? ??? ??, ??, ?? Go? ? ???? ???? 44 //go:generate ./some_runnable_command_here.sh Copt1 --opt2=foobar $ go generate $ go build $ go test
  • 45. ??? ?? ??? ??, ??, ?? Go? ? ???? ???? 45 cat <<< " package generated var BaseDir = "$BASEDIR" var Version = struct { ServerRevision string ProtocolRevision string DeployDate string }{ "$SERVER_HASH", "$PROTOCOL_HASH", "$DEPLOY_DATE", } " > generated/version.go
  • 46. ??? ?? ??? ??, ??, ?? Go? ? ???? ???? 46 type Ints []int func (a Ints) Val() []int func (a Ints) Copy() Ints func (a Ints) Cut(i int, j int) func (a Ints) Insert(i int, x int) Ints func (a Ints) Append(x ...int) Ints func (a Ints) Reverse() func (a Ints) Filter(f func(i int, value interface{}) bool) Ints func (a Ints) Each(f func(i int, value interface{})) func (a Ints) Map(f func(i int, value interface{}) int) Ints Type Int32s []int32 ...... Type Int64s []int64
  • 47. ??? ?? ??? ??, ??, ?? Go? ? ???? ???? 47 ? shell script? ??? ? ?? ??? ??? ?? ??? ??? ? ? Go, Python ?? ??? ??????? ? ??? ??? ??! ???, ???? ?? ?? ??? ? ? ? ?? ? ? ? Go? ast, parser ??? ??? ? ?? ? ??? ast, parser? ??? ??? ?? ?? ? ???? ??? ?? ? ??? ?? ?? ? ???? ??
  • 49. vim-go ??? ??? ?????? Go? ? ???? ???? 49
  • 50. Godeps ??? ??? ?????? Go? ? ???? ???? 50 ? Dependency Manager & Vendoring tool ? Copy all dependencies into Workspace directory ( ~= virtualenv in Python ) ? Fix Go version, Library version, { "ImportPath": "github.com/devsisters/gb-server", "GoVersion": "go1.4.2", "Deps": [ { "ImportPath": "golang.org/x/net/context", "Rev": "0b492c5a9642fa1365f77ad20bbb259a25572507" }, { "ImportPath": "golang.org/x/oauth2", "Rev": "ce5ea7da934b76b1066c527632359e2b8f65db97" }, { "ImportPath": "google.golang.org/api/googleapi", "Rev": "c34364630fd76916db716b46fd3a75403b161768" }, ....
  • 51. go-errors ??? ??? ?????? Go? ? ???? ???? var Crashed = errors.Errorf("oh dear") func Crash() error { return errors.New(Crashed) } if err != nil { if errors.Is(err, crashy.Crashed) { fmt.Println(err.(*errors.Error).ErrorStack()) } else { panic(err) } } 51
  • 52. GoConvey ??? ??? ?????? Go? ? ???? ???? http://goconvey.co/ 52
  • 53. GoConvey ??? ??? ?????? Go? ? ???? ???? http://goconvey.co/ 53
  • 54. GoConvey ??? ??? ?????? Go? ? ???? ???? http://goconvey.co/ 54
  • 55. Test function testing/quick ??? ??? ?????? Go? ? ???? ???? func TestOddMultipleOfThree(t *testing.T) { f := func(x int) bool { y := OddMultipleOfThree(x) return y%2 == 1 && y%3 == 0 } if err := quick.Check(f, nil); err != nil { t.Error(err) } } Target function Inject random valid parameter Check if target function is working well 55
  • 56. ??? ??? ?????? (??) (??) 4 56
  • 57. Cine ??? ??? ?????? Go? ? ???? ???? github.com/devsisters/cine ? Actor model for Go (like erlang) ? All actor is identified by unique PID ? Remote actor is treated same as local one ? Supports synchronous / asynchronous function call Cine Host 1 Host 2 Host 3 Actor Actor Actor Actor Actor 57
  • 58. Cine ??? ??? ?????? Go? ? ???? ???? github.com/devsisters/cine type Phonebook struct { cine.Actor book map[string]int } cine.Init("127.0.0.1:8000") phonebook := Phonebook{cine.Actor{}, make(map[string]int)} pid := cine.StartActor(&phonebook) // For asynchronous call (ignore all errors) cine.Cast(pid, nil, (*Phonebook).Add, "Jane", 1234) // For synchronous call ret, _ := cine.Call(pid, (*Phonebook).Lookup, "Jane") number := ret[0].(int) 58
  • 59. GoQuic ??? ??? ?????? Go? ? ???? ???? github.com/devsisters/goquic https://www.youtube.com/watch?v=hQZ-0mXFmk8 59
  • 60. ??? ??? ?????? Go? ? ???? ???? QUIC vs TCP+TLS+SPDY/HTTP2 ? 0-RTT support ? Multiplexing without Head-of-line blocking ? Forward error correction ? Connection Migration 60
  • 61. GoQuic ??? ??? ?????? Go? ? ???? ???? github.com/devsisters/goquic Chromium Extract QUIC core devsisters/ libquic Go binding w/ cgo devsisters/ goquic devsisters.github.io/goquic // server goquic.ListenAndServe(":8080", 1, nil) // client client := &http.Client{ Transport: goquic.NewRoundTripper(false), } resp, err := client.Get("http://example.com/") 61
  • 63. Q. ??? Go? ? ????? ?? ???? ???? Go? ? ???? ???? 63
  • 64. Q. ??? Go? ? ????? ?? ???? ???? Go? ? ???? ???? A. ???? ??? ???? ????????? ????? ????? ?? ? ?, ???? ?? ??? ?? ??? ??? ??? ? 64
  • 65. Q. ??? ???2 ?? ???? ???? Go? ? ???? ???? 65
  • 66. Q. ??? ???2 ?? ???? ???? Go? ? ???? ???? A. ????? (??) 66
  • 67. Q. ??? Go ??? ???? ???? Go? ? ???? ???? 67