私はgin gonicをHTTPフレームワークとして使用しており、次のように共有変数を使用していくつかのパスをグループ化する必要があります。
ur := r.Group("/")
ur.Use(package.Prepare)
{
ur.GET("/", package.Home)
}
Prepare
ハンドラー内ではpackage.tplPath
、各httpハンドラーのコードを書き直す代わりに、すべてのサブルートがこの変数にアクセスできるようにするために、パッケージ変数を宣言しています。
var tplPath = ""
func Prepare(c *gin.Context) {
_, filename, _, _ := runtime.Caller(0)
s := helper.RelativeFilePath(filename)
tplPath = s[1:len(s)] + "template/"
}
Goが各プロセスでどのように機能するか、および各HTTPリクエストの変数がわかりません。変数がパッケージレベルで宣言されている場合、各HTTPリクエストの後に設定されますか?
これは良い習慣と考えられますか?そうでない場合、なぜそうではないのですか?
これはスレッドセーフではなく、パッケージ変数はすべてのゴルーチン間で共有され、1つのルーチンでの変更は他のすべてのルーチンの値を変更し、データ競合を引き起こします。
一般に; 可能な場合は、パッケージレベル変数の使用を避けてください。
編集:
はじめに、パッケージは一種のモジュールです。特定のインポートパス(基本的にパッケージ名)のパッケージのインスタンスは1つだけ存在します。これは、パッケージレベルで変数のインスタンスが1つしかないことを意味します。
パッケージ変数は共有されたグローバルな状態です。その変数のすべてのアクセサーは、まったく同じメモリにアクセスします。
パッケージ変数のタイプ、構造体/文字列/整数などは関係ありません。パッケージレベルで定義されている場合、その変数のすべてのアクセサーは同じインスタンスを共有します。
(httpサーバーと同様に)並行コードがある場合、その変数の複数のアクセサーが同時に存在します。場合によっては、その変数が読み取られるだけの場合など、これで問題ありませんが、あなたの場合は変更されるようです。このコードを際どいものにしてください!
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加