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. THE STATE
    OF GO
    What's new since Go 1.12

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

  4. Agenda
    Changes to:
    ● the language
    ● the standard library
    ● the tooling
    ● the community

    View full-size slide

  5. CHANGES TO
    THE LANGUAGE

    View full-size slide

  6. - New number literals (1.13)
    - Overlapping interfaces can be embedded (1.14)
    Changes to the language
    6

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  13. 0x_A_A.d_bp8i

    View full-size slide

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

    View full-size slide

  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

    View full-size slide

  16. - New number literals
    - Overlapping interfaces can be embedded
    Changes to the language
    16

    View full-size slide

  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

    View full-size slide

  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.

    View full-size slide

  19. Standard Library

    View full-size slide

  20. ● Removal of SSLv3
    Breaking Changes
    20
    Go 1.14

    View full-size slide

  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!

    View full-size slide

  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

    View full-size slide

  23. ● Public keys: only 32 bytes
    ● Faster than RSA
    ● Publicly documented curve
    ● Not supported by any browsers (yet)
    Ed25519
    23
    Go 1.13

    View full-size slide

  24. Improved handling of:
    - Error wrapping
    - Checking error values
    - Checking error types
    Error handling
    24
    Go 1.13

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  28. Comparing wrapped errors
    err := readConfig()
    if errors.Is(err, os.ErrNotExist) {
    // file does not exist
    }
    Error handling
    28
    Go 1.13

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  37. ● 1.13: reflect .IsZero()
    ● 1.14: {T,B,TB}.Cleanup
    Testing
    37

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  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

    View full-size slide

  42. 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

    View full-size slide

  43. - 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
    GO111MODULE=on /dev/null /path/to/go.mod
    GO111MODULE=auto /path/to/go.mod

    View full-size slide

  44. Go modules on Subversion
    Go 1.13
    -

    View full-size slide

  45. godoc -http is no more
    Go 1.13

    View full-size slide

  46. 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

    View full-size slide

  47. 48
    ● Trims your your specific CI setup
    ● Making reproducible builds!
    Why go build -trimpath?
    Go 1.13

    View full-size slide

  48. 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

    View full-size slide

  49. 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

    View full-size slide

  50. 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

    View full-size slide

  51. 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

    View full-size slide

  52. 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

    View full-size slide

  53. Congratulations to tinygo on becoming a Google
    sponsored project!
    Tinygo, not so tiny budget!

    View full-size slide

  54. ▪ Added in Windows binaries
    ▫ Feature since Windows XP
    ▫ Marks memory as (non-)executable
    ▫ Enforced in the CPU
    Data Execution Prevention
    Go 1.14

    View full-size slide

  55. CTRL_CLOSE_EVENT
    CTRL_LOGOFF_EVENT
    CTRL_SHUTDOWN_EVENT
    Windows Events
    Go 1.14
    syscall.SIGTERM
    Windows Events
    Unix Syscalls

    View full-size slide

  56. WOMEN WHO GO & GOBRIDGE MEETUPS
    59
    7 more than 2019: 37 chapters now!

    View full-size slide

  57. Go Developer Network
    - 10k+ members
    - 172 meetups
    - 4.6k+ events
    - 137k+ RSVPs

    View full-size slide

  58. 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

    View full-size slide

  59. Slides
    bit.ly/sog-fosdem20

    View full-size slide

  60. Back in 2014

    View full-size slide

  61. Back in 2014
    @enneff
    @bradfitz

    View full-size slide

  62. Last year ...
    Last year

    View full-size slide

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

    View full-size slide

  64. 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

    View full-size slide

  65. THANKS!
    Francesc
    and
    Maartje
    76
    Gophers by Renee French, Ashley McNamara, Egon Elbre, Sam Croswell and Miguel Molina, Marcus Olsson
    Glenda by Renee French

    View full-size slide