17

golangパッケージ「net/http」は、グローバル変数DefaultServeMuxを使用してハンドラーを登録します。これは良い習慣と見なされますか、それともゴランイディオムと見なされますか?結局のところ、それはグローバル変数ですか?

グローバル変数を使用しない2つの主な理由は、1)複雑さを増す2)並行プログラムで問題があるというAFAIKです。

たぶん1)開発者はDefaultServerMuxを使用しないことを選択できるので、この場合は重要とは見なされませんか?2)はどうですか?Goではグローバル変数は常にスレッド/ゴルーチンで安全ですか?それでも、Goの標準ライブラリで使用されていることに驚いています。私は他の言語/標準ライブラリでそのような練習を見たことがありません。

4

2 に答える 2

23

結局のところ、それはグローバル変数ですか?

はい。変数はルートレベルで定義されるため、パッケージ全体でグローバルになります。

net/httpただし、これはパッケージのすべての重要な情報を格納するグローバル変数ではありません。net/httpこれは、パッケージのコンテンツを使用してユーザーにクイックスタートの機会を提供する便利なセットアップにすぎません。これはまた、それはそれほど複雑さを追加しないことを意味します。

これは良い習慣と見なされますか、それともゴランイディオムと見なされますか?

IMO、パッケージの使用についてユーザーを支援することをお勧めします。適切なデフォルト構成を提供することでユーザーの時間を節約できることがわかった場合は、そうしてください。

ただし、変数をエクスポートするときは注意が必要です。同時アクセスの準備をする必要があります。たとえば、(またはより良い、基礎となる)は、スレッドDefaultServeMuxセーフにするためにミューテックスを使用しています。ServeMux

Goではグローバル変数は常にスレッド/ゴルーチンで安全ですか?

いいえ。適切な同期(ミューテックス、チャネルなど)がないと、同時にアクセスされるすべてのものに問題が発生し、間違いなくすべてが断片的になります。

私は他の言語/標準ライブラリでそのような練習を見たことがありません。

loggingたとえば、Pythonのモジュールは、ルートロギングオブジェクトを取得する関数を提供します。この関数を呼び出して、ロギングの動作をカスタマイズできます。これは可変であり、モジュールで定義されているため、グローバルオブジェクトと見なすことができます。

于 2012-09-09T00:46:29.000 に答える
1

この場合、globvarは、たとえばパッケージ「log」に見られるアナログと同じくらい安全で適切な選択です。

IOW、クレーム1は可能な限り曖昧であり、クレーム2は制約されています。いつか/どこかでtrue、そうでない場合はfalse ==は、そのように使用されても一般的には成り立ちません。

于 2012-09-01T19:46:17.017 に答える