JMDC TECH BLOG

JMDCのエンジニアブログです

Go 1.26 リリースノート:主な新機能・変更点まとめ

みなさん、こんにちは!プロダクト開発部 製薬システム開発グループの西原です。

現在、製薬企業向けに提供しているヘルスビッグデータの分析を行うプロダクトであるJMDC Data Martのバックエンドの開発を担当しています。日々の開発では、主にGo言語を使用しています。

そこで本記事では、2月にリリース予定のGo 1.26で標準ライブラリにどのような変更が加えられたのか、その注目ポイントをまとめてご紹介します。詳細に入る前に、Go言語のリリースサイクルについておさらいします。

Goのリリースサイクル

GoはGo Release Cycleに則って安定したリリースサイクルを行っています。

go.dev

年2回のメジャーリリース

現在のリリースサイクルは、毎年1月中旬と7月中旬に開始されるように調整されています。

後方互換性の重視

Go 1.xの間は、古いバージョンで書かれたプログラムが新しいバージョンでも問題なくコンパイル・動作することが強く保証されています。

Go 1.26 で変わるところ

ここでは個人的に気になったトピックをいくつかピックアップしてご紹介します。

1. new(v) 構文の拡張(言語仕様の変更)

github.com

これまで、プリミティブ型(int, bool, stringなど)へのポインタを取得するには、一度変数に代入してからアドレスを取るか、ヘルパー関数を用意する必要がありました。Go 1.26からは、組み込み関数 new が拡張され、値を直接渡してそのポインタを取得できるようになります。

// サンプルコード

// Go 1.25 まで
age := 30
email := "alice@example.com"
isVerified := true

user := &User{
    Name:       "Alice",
    Age:        &age,
    Email:      &email,
    IsVerified: &isVerified,
}

// Go 1.26 から
user := &User{
    Name:       "Alice",
    Age:        new(30), 
    Email:      new("alice@example.com"),
    IsVerified: new(true),
}

これにより、「ポインタ渡し」のために、わざわざ変数定義やString("...")のようなヘルパー関数を使う必要がなくなります。

2. errors.AsType[T] による型安全なエラーハンドリング

github.com

エラーハンドリングを簡素化するジェネリクス関数 AsType が errors パッケージに追加されました。これまで errors.As を使う際は、ターゲットとなる変数を宣言し、そのポインタを渡す必要がありましたが、記述が冗長になりがちでした。

// サンプルコード

// Go 1.25 まで
var target *MyError
if errors.As(err, &target) {
    fmt.Println(target.Code)
}

// Go 1.26 から
if e, ok := errors.AsType[*MyError](err); ok {
    // e は *MyError 型として型推論される
    fmt.Println(e.Code)
}

3. log/slog のマルチハンドラー対応

github.com

log/slog に、MultiHandler 機能が追加されました。

これまでは、「ログを標準出力に流しつつ、同時にファイルにも保存したい」あるいは「エラーログだけは別の監視サービスにも送りたい」といった場合、自前でハンドラーを実装する必要がありました。

Go 1.26からは標準で複数のハンドラーをまとめる機能が提供され、以下のように簡単に実装できるようになりました。

// サンプルコード

fileHandler := slog.NewJSONHandler(file, nil)
stdoutHandler := slog.NewTextHandler(os.Stdout, nil)

// 複数のハンドラーへ同時に書き込む logger を作成
logger := slog.New(slog.NewMultiHandler(fileHandler, stdoutHandler))

logger.Info("Hello, World!") // 両方の出力先へ記録される

4. crypto/rand によるランダム文字列生成の簡略化

github.com

これまで Go で「ランダムな英数字の文字列(セッションIDなど)」を作ろうとすると少々手間がかかりました。

  1. make([]byte) でバッファを作る
  2. rand.Read() する
  3. base64 や hex でエンコードする

これが標準関数1つで安全にできるようになりました。

// サンプルコード

// Go 1.25まで
import (
    "crypto/rand"
    "encoding/base64"
)

func generateToken() (string, error) {
    b := make([]byte, 32)
    _, err := rand.Read(b)
    if err != nil {
        return "", err
    }

    return base64.URLEncoding.EncodeToString(b), nil
}

// Go 1.26から
import "crypto/rand"

func generateToken() {
    // アルファベットと数字からなる32文字のセキュアな文字列を生成
    token := rand.Text(32) 
    
    fmt.Println(token) // 例: "a8f3...9z1"
}

5. encoding/json/v2 の挙動変更

github.com

Go 1.25ではベータ版としてしか使えませんでした。Go 1.26では、encoding/json/v2 の導入が検討されています。 encoding/json/v2 ではパフォーマンス向上に加えて開発者の意図により沿った変更が多く含まれていますが、ここでは個人的に嬉しい変更点を2つ紹介します。

① map/slice のゼロ値(nil)が「空」として出力される

これまでは nil のスライスやマップは JSON の null として出力されていましたが、v2ではデフォルトで 空配列[]や 空オブジェクト{}として出力されるようになります。これにより、「null が返ってきてフロントエンドでエラーになる」といった事故を防ぎやすくなります。

② フィールド名のマッチングが厳密化

v1ではデコード時に大文字・小文字を区別しませんでしたが("name" に対して "NAME" も許容される)、v2ではデフォルトで大文字・小文字を厳密に区別するようになります。 これにより厳格なAPI定義が可能になります。表記ゆれがあるデータを扱う際はオプション(MatchCaseInsensitiveNames)の利用が必要です。

プロダクトにおけるアップデート戦略

今回も魅力的なバージョンアップデートがあるGo 1.26ですが、実際のプロダクトにどう適用していくかは戦略が必要です。ここでは、私たちのチームが普段どのようにGoのバージョンアップに向き合っているかをご紹介します。

1. 後方互換性を信頼しつつ、常に最新を保つ

Goは後方互換性の保証があるため、古いバージョンのままでも動作し続けることが多い言語です。しかし、「可能な限り常に最新バージョンに追従する」という方針をとっています。

コンパイラの最適化によるパフォーマンス向上や、セキュリティパッチの適用、そして将来的な技術的負債の蓄積を防ぐためです。

2. Renovateによる更新漏れの防止

バージョンアップを「忘れない」仕組みとして、依存関係更新ツールの Renovate を導入しています。

go.mod のGoバージョン指定や、CI/CDで使用するDockerイメージのタグ更新などは、手動で監視しているとどうしても漏れが発生します。Renovateを導入することで、Goの新しいマイナーバージョンやパッチバージョンがリリースされると自動的にPull Requestが作成されます。これにより、チームは「検知」のコストをゼロにし、「検証とマージ」のみに集中できる体制を整えています。

3. リリースタイミングの分離

アップデートを行うタイミングも重要視しています。私たちは「機能リリースがない時期」を狙ってGoのバージョン更新を行うようにしています。

もし「新機能のリリース」と「言語バージョンの更新」を同時に行って本番環境で不具合が起きた場合、原因の切り分けが非常に困難になるからです。「今回はGoのアップデートのみを行う」という期間を意図的に設けることで、万が一予期せぬ挙動(ライブラリの非互換や微妙な挙動変化など)が発生しても、迅速に原因を特定し、ロールバックなどの対応を取れるようにしています。

おわりに

今回は2月リリース予定のGo 1.26について取り上げさせていただきました。最後まで読んでいただきありがとうございました。

JMDCでは、ヘルスケア領域の課題解決に一緒に取り組んでいただける方を積極採用中です!フロントエンド / バックエンド / データベースエンジニア等、様々なポジションで募集をしています。詳細は下記の募集一覧からご確認ください。

hrmos.co

まずはカジュアルにJMDCメンバーと話してみたい/経験が活かせそうなポジションの話を聞いてみたい等ございましたら、下記よりエントリーいただけますと幸いです。

hrmos.co

★最新記事のお知らせはぜひ X(Twitter)、またはBlueskyをご覧ください!

twitter.com

bsky.app