標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

Go言語で、コンパイラのバージョンによって import 先を切り替える

"log/slog" の出力をS式化するアドオン sxlog-go というパッケージを開発しています。

"log/slog" は Go 1.21 で実装された標準ライブラリですが、ちょうど 1.21 で Windows 7, 8, Server 2008 R2 へのサポートは切られてしまいました。古い WindowsMicrosoft もサポートをきっていますが、世の中にはまだこっそり使われてる場所もあると思われます。

ですが、幸いにして "log/slog" の前身の "golang.org/x/exp/slog" はまだ今も更新されているようです。ということで、Go コンパイラのバージョンを見て、適切な側へ import 先を切り変えるようにしてみました。

(1) go.mod のバージョンを 1.20 におとす

go.mod

--- a/go.mod
+++ b/go.mod
@@ -1,5 +1,7 @@
 module github.com/hymkor/sxlog-go

-go 1.24.5
+go 1.20

(2)バージョンごとにソースを分ける

Go 1.21+ 向け

go121.go

//go:build go1.21

package sxlog

import (
    "log/slog"
)

Go 1.20 まで

go120.go

//go:build !go1.21

package sxlog

import (
    // This version is compatible with Go 1.20.
    // Only versions up to v0.0.0-20240904232852-e7e105dedf7e are supported.
    "golang.org/x/exp/slog"
)

(3)go get する

Go 1.20.15 は go1.20.15(.exe) という実行ファイル名で参照できるようになっているとすると、

> go1.20.14 get golang.org/x/exp/slog

でよいはずだが、最新版は既に「要 Go 1.24」になっており、次のようなエラーが発生する。

golang.org/x/exp/slog imports
        golang.org/x/exp/slices imports
        cmp: package cmp is not in GOROOT (C:\Users\hymko\sdk\go1.20.14\src\cmp)
note: imported by a module that requires go 1.24
golang.org/x/exp/slog imports
        golang.org/x/exp/slices imports
        slices: package slices is not in GOROOT (C:\Users\hymko\sdk\go1.20.14\src\slices)
note: imported by a module that requires go 1.24

そこで Go 1.20 をサポートする最後のバージョンを go get する。

> go1.20.14 get golang.org/x/exp/slog@v0.0.0-20240904232852-e7e105dedf7e

( …Go 1.20 という4世代前のバージョンを使うのは、いろいろと無理があることは否めない )

(4)型エイリアスで違いを吸収する

メインロジックのソースで import してしまうと、全ソースを 1.20 までと1.21 以降で複写しなくてはいけないので、型エイリアスを使ってメインロジックでは import せずに slog パッケージの型を参照できるようにする。

の双方で以下を記述

type slogLevel = slog.Level

type slogRecord = slog.Record

type slogAttr = slog.Attr

type slogHandler = slog.Handler

".../slog" を import していない メインロジック では、slog の型を直接使わず、これらの型 slogXXXXX を使うようにすればよい

(5)サンプルを2バージョン用意

以上