LoginSignup
1
0

More than 1 year has passed since last update.

StaticCheckは同じパッケージ内のdeprecated要素の参照を無視する

Posted at

TL; DR

  • 廃止予定(deprecated) の関数、変数を同じパッケージ内から参照しても staticcheck は警告しない
  • この挙動は意図的(staticcheck は廃止予定の要素が「外部から参照される」ことを禁止している)
// DeprecatedFunc shows some messages.
//
// Deprecated: should not be used.
func DeprecatedFunc() {
	fmt.Println("hoge")
}

// NewFunc shows some messages.
func NewFunc() {
	DeprecatedFunc() // ここはstaticcheckで警告されない!!
}

はじめに

staticcheckは、廃止予定の関数、変数を参照している箇所を警告してくれます。golangci-lintに標準で入っているので使っている方も多いと思います。

Goでは廃止予定の要素には // Deprecated: ... というコメントを書く決まりがあるため、この行を検知しています。

foo/foo.go
package foo

import "fmt"

// DeprecatedFunc shows some messages.
//
// Deprecated: should not be used.
func DeprecatedFunc() {
	fmt.Println("hoge")
}
main.go
package main

import "example.com/foo"

func main() {
	foo.DeprecatedFunc()
}
$ staticcheck
main.go:6:2: foo.DeprecatedFunc is deprecated: should not be used.  (SA1019)

一方、冒頭のように同じパッケージ内であれば廃止予定の要素を参照しても警告されません。
最初はバグかと思いましたが、この仕様は意図的なものでした。

パッケージ内の参照を無視しない理由

廃止予定API利用のチェックは、同じパッケージからの廃止予定のものの利用を明示的に許可しています。つまり、新しい、廃止予定ではないAPIを内部的に廃止予定APIの上に構築することができます。何かが廃止予定であるということは、別のパッケージやサードパーティーの利用者にしか影響しません。廃止予定の方の(埋め込み)フィールドを持つことも問題ない場合もあります。

The check for use of deprecated APIs explicitly allows the use of deprecated things from the same package. After all, a new, not deprecated API can internally be built upon a deprecated API. That something is deprecated only affects other packages, 3rd party users. Even having (embedded) fields of deprecated types can be fine sometimes.

確かに、新APIへの過渡期には旧APIの実装を参照することがあると思います。「レガシーコード改善ガイド」に登場した「スプラウトメソッド」の話を思い出しました。

おわりに

以上、staticcheckのdeprecatedチェックの仕様についてでした。内部でさえ使いたくないものについては、レビューで確認するしかなさそうです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0