The State of Go 2020

The State of Go 2020

The most important changes to Go since Go 1.12.
By Maartje Eyskens and Francesc Campoy

D8e5d79ca42edc07693b9c1aacaa7e5e?s=128

Francesc Campoy Flores

February 02, 2020
Tweet

Transcript

  1. THE STATE OF GO What's new since Go 1.12

  2. bit.ly/sog-fosdem20 Maartje Eyskens @maartjeme Francesc Campoy @francesc

  3. What's new since Go 1.12 ▪ Go 1.13 ▫ Released

    September 3rd 2019 ▪ Go 1.14 ▫ Expected February 2020 ▫ Beta 1 released 17 December 2019
  4. Agenda Changes to: • the language • the standard library

    • the tooling • the community
  5. CHANGES TO THE LANGUAGE

  6. - New number literals (1.13) - Overlapping interfaces can be

    embedded (1.14) Changes to the language 6
  7. • Added binary literals fmt.Println(0b101) // 5 • Alternative syntax

    for octal literal fmt.Println(0o10, 0O10, 010) // 8 8 8 • All number formats can now be imaginary fmt.Println(0b111i) // (0+7i) New number literals 7 Go 1.13
  8. • Hexadecimal literals can now have: ◦ floating point: ▪

    1.2 = 1×160 + 2×16-1 = 1.125 ◦ exponent ▪ 1p3 = 1×160 × 23 = 8 • Example: 0xa.cp3 | a.c = 10x160 + 12x16-1 = 10.75 | p3 = 23 = 8 | a.cp3 = 10.75 x 8 = 86 New number literals 8 Go 1.13
  9. • Relatedly, shift counters can now be signed s :=

    int64(2) fmt.Println(1 << s) // 8 • But the following program will panic s := int64(-2) fmt.Println(1 << s) // panic: runtime error: negative shift amount New number literals 9 Go 1.13
  10. • You can separate digits and/or their base with _

    fmt.Println(1_000_000) // 1000000 fmt.Println(0b_1_0000) // 16 New number literals 10 Go 1.13
  11. ParseInt support underscores only in “base guessing” mode. strconv.ParseInt("1_000", 0,

    0) // 1000 strconv.ParseInt("0b1_000", 0, 0) // 8 strconv.ParseInt("0o1_000", 0, 0) // 512 strconv.ParseInt("0x1_000", 0, 0) // 4096 Otherwise, it will fail the same way it would fail with explicit base. strconv.ParseInt("0b1_000", 2, 0) // invalid syntax strconv.ParseInt("0b1000", 2, 0) // invalid syntax strconv.ParseInt("1000", 2, 0) // 8 A note on strconv.ParseInt 11 Go 1.13
  12. Good ideas: - 1_000_000 / / a million - 2_02_2020

    / / today! - 0x_FF_AA_EE / / #pink Bad ideas: - 0x15p1 / / 42 - ... Good ideas / bad ideas 12 Go 1.13
  13. 0x_A_A.d_bp8i

  14. 0x1p000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000001 A bug?

  15. Try this at home! New printing verb %O and new

    behavior for %X. fmt.Printf("%x\n", 10) // a fmt.Printf("%x\n", 10.0) // 0x1.4p+03 fmt.Printf("%O\n", 10) // 0o12
  16. - New number literals - Overlapping interfaces can be embedded

    Changes to the language 16
  17. Before Go 1.14, this code would fail. type ReadWriteCloser interface

    { io.ReadCloser io.WriteCloser } If the repeated methods have same signature, it’s valid code. Before Go 1.14, this code would fail. type ReadWriteCloser interface { io.ReadCloser io.WriteCloser // duplicate method Close } If the repeated methods have same signature, it’s valid code. Overlapping interfaces 17 Go 1.14
  18. Overlapping interfaces 18 Go 1.14 type MyCloser interface { Close()

    } type MyReadCloser interface { io.ReadCloser MyCloser // duplicate method Close } This code is still incorrect, since the method types differ.
  19. Standard Library

  20. • Removal of SSLv3 Breaking Changes 20 Go 1.14

  21. • runtime.Goexit can no longer be aborted by a recursive

    panic/recover func maybeGoexit() { defer func() { fmt.Println(recover()) }() defer panic("cancelled Goexit!") runtime.Goexit() } func main() { maybeGoexit() fmt.Println("Hello, FOSDEM!") } Breaking Changes 21 Go 1.14 ~ $ go run . Cancelled Goexit! Hello FOSDEM!
  22. • End of SSLv3 • CA path for Alpine 3.7+

    added ◦ /etc/ssl/cert.pem ◦ Not an issue as Alpine also links /etc/ssl/certs/ca-certificates.crt ◦ Still need apk add ca-certificates What’s up with TLS 22
  23. • Public keys: only 32 bytes • Faster than RSA

    • Publicly documented curve • Not supported by any browsers (yet) Ed25519 23 Go 1.13
  24. Improved handling of: - Error wrapping - Checking error values

    - Checking error types Error handling 24 Go 1.13
  25. func main() { err := readConfig() if err == os.ErrNotExist

    { } } Issues: • No good ability to pass additional context • Hacky advanced checks Error handling: the problem 25 Go 1.13
  26. Wrapping errors %w in fmt.Errorf() func readConfig() error { f,

    err := os.Open("config.json") if err != nil { return fmt.Errorf("Cannot open config.json: %w", err) } } Error handling: the solution 26 Go 1.13
  27. Error Wrapping Before: return fmt.Errorf("Call failed: %v", err) fmt.Printf("%T", err)

    // *err.stringError Now: return fmt.Errorf("Call failed: %w", err) fmt.Printf("%T", err) // *err.wrapError Error handling: the solution 27 Go 1.13
  28. Comparing wrapped errors err := readConfig() if errors.Is(err, os.ErrNotExist) {

    // file does not exist } Error handling 28 Go 1.13
  29. Error type checking err := readDatabase() var e *QueryError if

    errors.As(err, &e) { // err is type QueryError // also works with wrap! } Error handling 29 Go 1.13
  30. os.UserConfigDir() (string, error) $XDG_CONFIG_HOME, $HOME/.config on Linux $HOME/Library/Application Support on

    Darwin %AppData% on Windows Similar function added last year: os.UserHomeDir() (string, error) // 1.12 os 30 Go 1.13
  31. • New package in Go 1.14. • Fast hash functions

    on by sequences. • Perfect for hash tables and similar. hash/maphash 31 Go 1.14
  32. It is the fastest hashing function in the Go standard

    library. # go test -bench=. BenchmarkCRC64-2 55501 21247 ns/op BenchmarkCRC32-2 55454 20055 ns/op BenchmarkFNV-2 99736 10743 ns/op BenchmarkFNVa-2 108721 10475 ns/op BenchmarkAdler32-2 313054 4004 ns/op BenchmarkMaphash-2 475030 2477 ns/op Is it the fastest hashing function available in Go? hash/maphash 32 Go 1.14
  33. Let’s compare to xxHash. # go test -bench=. BenchmarkCRC64-2 55501

    21247 ns/op BenchmarkCRC32-2 55454 20055 ns/op BenchmarkFNV-2 99736 10743 ns/op BenchmarkFNVa-2 108721 10475 ns/op BenchmarkAdler32-2 313054 4004 ns/op BenchmarkMaphash-2 475030 2477 ns/op BenchmarkXXHash-2 1470511 747 ns/op github.com/cespare/xxhash hash/maphash 33 Go 1.14
  34. The implementation exposes the existing code in the runtime. //go:noescape

    //go:linkname runtime_memhash runtime.memhash func runtime_memhash(p unsafe.Pointer, seed, s uintptr) uintptr hash/maphash 34 Go 1.14
  35. Compare to how it was being used from dgraph-io/ristretto: //go:noescape

    //go:linkname memhash runtime.memhash func memhash(p unsafe.Pointer, h, s uintptr) uintptr type stringStruct struct { str unsafe.Pointer len int } func MemHash(data []byte) uint64 { ss := (*stringStruct)(unsafe.Pointer(&data)) return uint64(memhash(ss.str, 0, uintptr(ss.len))) } hash/maphash 35 Go 1.14
  36. Let’s compare to xxHash. # go test -bench=. BenchmarkCRC64-2 55501

    21247 ns/op BenchmarkCRC32-2 55454 20055 ns/op BenchmarkFNV-2 99736 10743 ns/op BenchmarkFNVa-2 108721 10475 ns/op BenchmarkAdler32-2 313054 4004 ns/op BenchmarkMaphash-2 475030 2477 ns/op BenchmarkXXHash-2 1470511 747 ns/op BenchmarkMemhash-2 4106250 293 ns/op github.com/dgraph-io/dgraph hash/maphash 36 Go 1.14
  37. • 1.13: reflect .IsZero() • 1.14: {T,B,TB}.Cleanup Testing 37

  38. reflect.ValueOf(0).IsZero() // true reflect.ValueOf("").IsZero() // true reflect.ValueOf(struct{}{}).IsZero() // true reflect.ValueOf([]string{}).IsZero()

    // false reflect.ValueOf([]string(nil)).IsZero() // true Testing: reflect IsZero 38 Go 1.13
  39. The testing package now supports cleanup functions on T, B,

    and TB. func Test_something(t *testing.T) { t.CleanUp(func() { fmt.Println("Clean up!") }) t.Run(tt.name,[...]) } This is useful with parallel tests and subtests Testing: Cleanup 39 Go 1.14
  40. • 2 new methods on Duration: Microseconds and Milliseconds time.Second.Milliseconds()

    // 1_000 time.Second.Microseconds() // 1_000_000 Time 40 Go 1.13
  41. Implementation: func (d Duration) Microseconds() int64 { return int64(d) /

    0X1.F4P+09 } func (d Duration) Milliseconds() int64 { return int64(d) / 0X1.E848P+19 } Time 41 Go 1.13
  42. TOOLING

  43. Impossible not to talk about them, but too much to

    say. - GO111MODULE=auto doesn’t check GOPATH - GOSUMDB (sum.golang.org) - enables first time verification of modules - GOPRIVATE: manage GONOPROXY/GONOSUMDB - GOINSECURE: #YOLO. Go Modules 43
  44. - You can set GO111MODULE to on, off, or auto

    (default) - Modules are enabled in auto when the current directory, or one of its parents, contains a go.mod file. - The read-only GOMOD variable indicates in which mode you are. - Output of go env GOMOD: Go Modules: enabling 44 go.mod not found go.mod found GO111MODULE=off <nothing> <nothing> GO111MODULE=on /dev/null /path/to/go.mod GO111MODULE=auto <nothing> /path/to/go.mod
  45. Go modules on Subversion Go 1.13 -

  46. godoc -http is no more Go 1.13

  47. go build -trimpath Go 1.13 ~ $ go build .

    && ./hello panic: Hello FOSDEM goroutine 1 [running]: main.main() /home/user/go/src/github.com/meyskens/state-of-go/panic.go:4 +0x39 ~ $ go build -trimpath . && ./hello panic: Hello FOSDEM goroutine 1 [running]: main.main() command-line-arguments/panic.go:4 +0x39
  48. 48 • Trims your your specific CI setup • Making

    reproducible builds! Why go build -trimpath? Go 1.13
  49. RUNTIME

  50. Better errors for out of range Given this buggy code:

    a := []int{1, 2, 3} fmt.Println(a[3]) In 1.12 and before: panic: runtime error: index out of range Since 1.13: panic: runtime error: index out of range [3] with length 3 Go 1.14
  51. Defer got much faster for many cases! - basically as

    fast as a normal function call benchmark 1.12 ns/op 1.14 ns/op delta BenchmarkDefer-32 67.6 7.31 -89.19% BenchmarkDefer10-32 57.5 59.3 +3.13% BenchmarkDeferMany-32 157 168 +7.01% change: cmd/compile, cmd/link, runtime: make defers low-cost through inline code and extra funcdata Performance: defer Go 1.14
  52. JSON encoding/decoding is faster! - 9% faster encoding - 38%

    faster decoding benchmark 1.12 MB/s 1.14 MB/s speedup BenchmarkCodeEncoder-32 2139.27 2332.60 1.09x BenchmarkCodeMarshal-32 2178.14 2113.87 0.97x BenchmarkCodeDecoder-32 364.06 503.32 1.38x BenchmarkUnicodeDecoder-32 30.25 37.16 1.23x BenchmarkCodeUnmarshal-32 351.67 353.34 1.00x change: encoding/json: speed up tokenization of literals Performance: JSON Go 1.14
  53. Many improvements! - fewer bound checks - time.Timer is more

    performant - scheduling more efficient for high contention mutexes - and much more ... Performance: more Go 1.14
  54. PORTS ▪ Go 1.13 Android 10 ▪ Go 1.13 requires

    macOS 10.11 or later ▪ Go 1.14 last to support darwin/arm(32) ▪ Go 1.14 added freebsd/arm64 ▪ Go 1.14 might support Dragonfly, Illumos, Solaris ▪ Go 1.14 dropped NaCl
  55. Congratulations to tinygo on becoming a Google sponsored project! Tinygo,

    not so tiny budget!
  56. ▪ Added in Windows binaries ▫ Feature since Windows XP

    ▫ Marks memory as (non-)executable ▫ Enforced in the CPU Data Execution Prevention Go 1.14
  57. CTRL_CLOSE_EVENT CTRL_LOGOFF_EVENT CTRL_SHUTDOWN_EVENT Windows Events Go 1.14 syscall.SIGTERM Windows Events

    Unix Syscalls
  58. COMMUNITY

  59. WOMEN WHO GO & GOBRIDGE MEETUPS 59 7 more than

    2019: 37 chapters now!
  60. Go Developer Network - 10k+ members - 172 meetups -

    4.6k+ events - 137k+ RSVPs
  61. conferences ▪ Go Devroom @ FOSDEM 2020 (you are here)

    ▪ Gophercon Israel, Tel Aviv February 3 ▪ CaptialGo, Washington DC March 27 ▪ Gophercon India, Goa March 28-29 ▪ Gophercon Russia, Moscow March 28 ▪ dotGo, Paris March 30 ▪ Gophercon Europe, Berlin April 23-26
  62. None
  63. Slides bit.ly/sog-fosdem20

  64. Back in 2014

  65. Back in 2014 @enneff @bradfitz

  66. 2015 ...

  67. 2016 ...

  68. 2017 …

  69. 2018 ...

  70. Last year ... Last year

  71. And this year!! (Sunday morning is hard)

  72. Today

  73. SCHEDULE

  74. SCHEDULE

  75. Lightning Talks: bit.ly/golight2020 ▪ 16:00 till 17:00 in UB2.525a (here)

    ▪ 8 minutes ▪ CfP deadline: Today 14:30 (Brussels time, duh) ▪ Submit at: bit.ly/golight2020
  76. THANKS! Francesc and Maartje 76 Gophers by Renee French, Ashley

    McNamara, Egon Elbre, Sam Croswell and Miguel Molina, Marcus Olsson Glenda by Renee French