いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-165 (Go 1.18 Beta1 がリリース)

概要

Go 1.18 Beta 1 がリリースされましたね。

go.dev

遂にGoもジェネリック時代に突入って感じ。個人的には今までジェネリック無いと困る!って状況にはなったことないのですが、あるのは便利ですよね。

個人的には 1.18 で入る予定?のマルチモジュールワークスペースの方に期待大です。

てことで、少し試してみました。

Dockerfile

マシンにインストールするのはちょっと嫌だったのでコンテナ上げて試してみることにしました。

こんな感じでDockerfileを作成

# syntax=docker/dockerfile:1-labs
FROM golang:1.18beta1-alpine

USER root
RUN <<EOF
        apk add --no-cache bash vim git ctags sudo
        adduser -h /home/dev -s /bin/bash dev
        adduser dev wheel
        echo "dev:dev" | chpasswd
        echo '%wheel ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/wheel
        chown -R dev:wheel /go
EOF

USER dev
RUN <<EOF
        git clone https://gist.github.com/1a16cd5b551fe4e76ae941abb658b893.git vimrc
        cp vimrc/.vimrc ~
        rm -rf vimrc/
        go install golang.org/x/tools/cmd/goimports@latest
        go clean -modcache
EOF
WORKDIR /workspace

CMD [ "bash" ]

以下のようにしてイメージをビルド

$ docker image build -t go1.18beta1 ${PWD}

バージョン確認

コンテナを以下のようにして起動して

$ docker container run -it --rm go1.18beta1

バージョンを確認

bash-5.1$ go version
go version go1.18beta1 linux/amd64

うん。ちゃんと 1.18 beta1 ですね。

ジェネリックをちょっとだけ試してみる

実際に勉強するのは 1.18 が出てからにするとして、少しだけ試してみました。

こんな感じであってるのかしら?。。。

package main

import (
        "context"
        "fmt"
        "time"

        "github.com/devlights/gomy/ctxs"
)

type addable interface {
        int | ~string
}

func main() {
        ctx, cxl := context.WithTimeout(context.Background(), 10*time.Millisecond)
        defer cxl()

        ctx1, ch1 := add(ctx, 999)             // type parameters inferred
        ctx2, ch2 := add[string](ctx, "hello") // type parameters specified

        ctx3 := pri[int](ctx, ch1) // type parameters specified
        ctx4 := pri(ctx, ch2)      // type parameters inferred

        // wait until all contexts is done
        <-ctxs.WhenAll(ctx, ctx1, ctx2, ctx3, ctx4).Done()
}

func add[V addable](pCtx context.Context, item V) (context.Context, <-chan V) {
        ctx, cxl := context.WithCancel(pCtx)
        ch := make(chan V)
        go func() {
                defer cxl()
                defer close(ch)
                for i := 0; i < 5; i++ {
                        select {
                        case <-ctx.Done():
                                break
                        default:
                                ch <- item
                        }
                }
        }()
        return ctx, ch
}

func pri[V addable](pCtx context.Context, ch <-chan V) context.Context {
        ctx, cxl := context.WithCancel(pCtx)
        go func() {
                defer cxl()
                for v := range ch {
                        select {
                        case <-ctx.Done():
                                break
                        default:
                                fmt.Println(v)
                        }
                }
        }()
        return ctx
}

実行してみる。

bash-5.1$ go run main.go
999
999
999
999
hello
hello
hello
hello
999
hello

ちゃんと動いてますね。

参考情報

go.dev

go.dev

www.youtube.com

go.dev

go.googlesource.com

tip.golang.org


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com