Go1.19~のsync/atomicの新旧APIの使い分け
Go1.19のリリースでsync/atomicに型が追加され、メソッド経由でアトミック操作が行えるようになりました
新しく実装する箇所に関しては基本的に新しいAPIを利用するのが推奨されます
先日仙台で開催されたGo Conference mini 2022 Autumn IN SENDAIでこのアップデートの内容について話したのですが、 従来のAPIがDeprecated(非推奨)にならない理由について説明が不足していたため、それを補足するための記事になります
YouTubeのvideoIDが不正です
従来のAPIはDeprecatedにはならない
従来のAPIでやれることは全て実現でき、利便性も高い完全上位互換な機能が生まれたため、従来のAPIはDeprecatedにしてしまった方が良いのではと思い、proposalを投稿しました
議論の結果、提案は却下されています
APIの利用方法が変わっている
例えば構造体がもつフィールドをアトミック操作の対象にしたい場合、以下のようにフィールドの型と関数を呼び出す実装を変更する必要があります
type Foo struct {
Counter int64
}
func (f *Foo) Count() {
atomic.AddInt64(&f.Counter, 1)
}
---
type Foo struct {
Counter atomic.Int64
}
func (f *Foo) Count() {
f.Counter.Add(1)
}
これは変更としては大きく、Deprecatedにしてしまうと警告の対応に開発者の時間を多く消費してしまいます
proposalへのフィードバック#issuecomment-1254702555
似たような事例でioutilパッケージをDeprecatedにする提案がありました
今回のproposalと異なる点としては、ioutilの古いAPIと代替の新しいAPIのシグネチャがほとんど同じで、開発者が対応しやすいものとなっていました
また、ioutilの廃止によって余分なコードのインポートが減るというメリットもありました
従来のAPIが警告を出すほど壊れていない
MD5やmath/rand.Readなど他の非推奨化が予定されている機能は、利用されることでプログラムに直接的に問題を与えてしまう可能性があります
これらと比較すると、sync/atomicの従来のAPIは、多少利便性に欠けるものの利用されることによる問題がそれほど大きくないため非推奨にする必要はないと判断されました
proposalへのフィードバック#issuecomment-1261240285
まとめ
警告の対応により、開発者の時間を取る割にはあまりメリットがないため、従来のAPIは非推奨にはならないですが、以下の理由により新しく実装する箇所に関しては新しいAPIを利用するのが良いです
- アトミック操作されるべき箇所がわかりやすく、安全なコードが書ける
- Pointer型が型パラメータで型を指定でき便利(標準パッケージでgenericsが使われた初めての事例)
- 従来のAPIでやれることは新しいAPIで全て実現できる
Discussion