Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Francesc Campoy Flores

February 02, 2020
Tweet

More Decks by Francesc Campoy Flores

Other Decks in Programming

Transcript

  1. 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
  2. - New number literals (1.13) - Overlapping interfaces can be

    embedded (1.14) Changes to the language 6
  3. • 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
  4. • 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
  5. • 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
  6. • 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
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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.
  12. • 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!
  13. • 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
  14. • Public keys: only 32 bytes • Faster than RSA

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

    - Checking error types Error handling 24 Go 1.13
  16. 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
  17. 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
  18. 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
  19. 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
  20. 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
  21. • New package in Go 1.14. • Fast hash functions

    on by sequences. • Perfect for hash tables and similar. hash/maphash 31 Go 1.14
  22. 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
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. • 2 new methods on Duration: Microseconds and Milliseconds time.Second.Milliseconds()

    // 1_000 time.Second.Microseconds() // 1_000_000 Time 40 Go 1.13
  29. 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
  30. 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
  31. - 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
  32. 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
  33. 48 • Trims your your specific CI setup • Making

    reproducible builds! Why go build -trimpath? Go 1.13
  34. 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
  35. 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
  36. 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
  37. 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
  38. 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
  39. ▪ Added in Windows binaries ▫ Feature since Windows XP

    ▫ Marks memory as (non-)executable ▫ Enforced in the CPU Data Execution Prevention Go 1.14
  40. 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
  41. 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
  42. THANKS! Francesc and Maartje 76 Gophers by Renee French, Ashley

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