Programmingミドル/リード Go 開発者

Goにおけるパッケージと可視性の特徴について説明してください。エクスポートされるオブジェクトとエクスポートされないオブジェクトはいつ、どのように使用すべきですか?

Hintsage AIアシスタントで面接を突破

回答

Goでは、変数、関数、構造体、およびメソッドの可視性は最初の文字の大文字小文字に密接に関連しています:

  • 名前が大文字で始まる場合 — オブジェクトはパッケージの外部にエクスポートされます。
  • 名前が小文字で始まる場合 — オブジェクトは自分のパッケージ内でのみアクセス可能です。

ファイル example.go:

package mypkg var ExportedVar int // 他のパッケージからアクセス可能 var unexportedVar int // mypkg内のみアクセス可能

パッケージをインポートすると、エクスポートされたオブジェクトのみにアクセスできます。

ベストプラクティス:

  • 実装の詳細を隠し、必要な型と関数のみをエクスポートします。
  • プライベートな定数や関数には小文字の名前を使用します。

問題のある質問

質問: "エクスポートされていないフィールドを持つ構造体をエクスポートできますか?そのようなフィールドを別のパッケージで使用しようとするとどうなりますか?"

回答: エクスポートされるのは大文字で始まる構造体のみです。小文字で始まるすべてのフィールドはパッケージの外部からはアクセスできません。 そのようなフィールドに外部からアクセスしようとすると、コンパイルエラーになります。

例:

// package user type User struct { Name string // エクスポートされたフィールド age int // userパッケージの外部からはアクセス不可 }

他のパッケージで:

u := user.User{Name: "Ivan"} u.age = 42 // コンパイルエラー: age is not accessible

実際のエラーの例


ストーリー

JSONマーシャリングによるデータの損失: REST APIで構造体をエクスポートしましたが、フィールドをエクスポートせず(小文字にした)結果、JSONへのマーシャルにこれらのフィールドが含まれず、APIユーザーは必要な情報を得られませんでした。


ストーリー

必要な関数へのアクセスが機能しない: チームは便利なユーティリティを別のパッケージに移動しましたが、名前を大文字にするのを忘れました。関数はアクセス不可となり、インターフェースを再構築する必要がありました。


ストーリー

コード自動生成時の名前の衝突: 同じパッケージ内で大文字小文字が異なる同名の変数を使用してコードを生成しました。スクリプトの一つがエクスポートされた定数を小文字の名前に誤って変更しました。その結果、アプリケーションはこの定数へのグローバルアクセスを失い、一部の機能が利用できなくなりました。