What is new in Go 1.18


This image is attributed to Maria Letta.
Original gopher image is attributed to Renee French.

What’s new in Go 1.18

This Day 2 post of the Merpay Tech Openness Month 2022 is brought to you by @guha from the Merpay IDP team.

On Day 2 of Merpay’s Tech Openness month, let’s take a look at what’s new with the open-source language that is the backbone of the tech stack at Mercari.
If Go 1.18 upgrade PRs are already hitting your slack channels, before you put on your reviewer’s hats, here’s a brief rundown on what’s new in the biggest upgrade the language has ever seen.


This image is attributed to Maria Letta.
Original gopher image is attributed to Renee French.

Generics

Generics are a way of writing code that is independent of the types being used. Starting from Go 1.18 functions and types may now be written to use any of a set of types.

Steve Francia*, the Head of Product of the Go language, feels that the big deal with the lack of support for Generics is that Go devs have had to explicitly define each type or the behavior for each type, over and over again, even when the behavior is common, leading to repetitive and in some cases, performance inhibiting code.

The ID Platform in Merpay, providing authorization and authentication to all Mercari businesses, is continuously working to expand the gamut of services and features we offer, and as such, the support for generics should be a great boon to our productivity, allowing us to spin up new services which share common behavior with existing ones with the addition of minimal, consolidated, and readable code, which has the same type safety that Go has always provided.

For those interested in diving right in, see this tutorial right from the horse’s mouth, and the updated language spec.

package main

import "golang.org/x/exp/constraints"

func main() {
    intMin := GMin[int]
    println(intMin(100, 200))

    floatMin := GMin[float64]
    println(floatMin(2.71, 3.14))
}

func GMin[T constraints.Ordered](x, y T) T {
    if x < y {
        return x
    }
    return y
}

Simple generic function.
Go playground: https://go.dev/play/p/M6v_hwVP2fo

Native support for Fuzzing

Fuzzing is a type of vulnerability testing that throws arbitrary data at a piece of code to expose unexpected errors. Some vulnerabilities that can be exposed by fuzzing are SQL injection, buffer overflow, denial of service, and cross-site scripting attacks.

Go 1.18 makes Go the first major language to provide native support for fuzzing.
Go’s approach to fuzzing provides extra security for the current code as well as ongoing protection as code and dependencies evolve.

Tests are at the core of development in the ID Platform, as we run critical services that need to be hardened against all vulnerabilities. Toolchain support for fuzzing will allow our engineers to catch vulnerabilities and prevent attacks without the need for third-party integrations. More secure services with minimal overhead.

For more on how to write a fuzzy test in Go 1.18, jump right into Go’s own tutorial.

package fuzz

import (
    "net/url"
    "reflect"
    "testing"
)

func FuzzParseQuery(f *testing.F) {
    f.Add("x=1&y=2")
    f.Fuzz(func(t *testing.T, queryStr string) {
        query, err := url.ParseQuery(queryStr)
        if err != nil {
            t.Skip()
        }
        queryStr2 := query.Encode()
        query2, err := url.ParseQuery(queryStr2)
        if err != nil {
            t.Fatalf("ParseQuery failed to decode a valid encoded query %s: %v", queryStr2, err)
        }
        if !reflect.DeepEqual(query, query2) {
            t.Errorf("ParseQuery gave different query after being encoded\nbefore: %v\nafter: %v", query, query2)
        }
    })
}

Example fuzz test testing the behavior of the net/url package

Go Workspaces

Ever wanted to work across multiple go modules at the same time ? Now you can!
Go 1.18 introduces multi-module workspaces in Go. With multi-module workspaces, you can tell the go command that you’re writing code in multiple modules at the same time and easily build and run code in those modules.

In the ID Platform team, we collaborate closely with other teams and codeowners, own multiple repositories and manage shared internal libraries. Being able to add to a version of a go module while a different version is released and cached in the remote library can be a great boost to our productivity and flexibility.

Here’s Go’s tutorial on Getting started with multi-module workspaces.

20% Performance Improvements

Go 1.18 brings CPU performance improvements of up to 20% to Apple M1, ARM64, and PowerPC64 processors.
In the IDP team, we love performance improvements, what more can we say?

This article briefly highlights each major feature in Go 1.18 but is not meant to be a tutorial or guide on how to use any of them. Go’s own documentation does that much better than this author could and the relevant pages are linked above.

For an exhaustive list of what’s new in Go 1.18 please check out the release notes.

*Steve Francia has the unique distinction of having held leadership roles in 5 of the “Top 100” open source projects in the world (Go, Docker, Hugo, MongoDB, Drupal).

Tomorrow’s article will be by @sinmetal. Look forward to it!

  • X
  • Facebook
  • linkedin
  • このエントリーをはてなブックマークに追加