【GO】外部パッケージのレシーバ定義


golangではtypeによる型定義とレシーバと呼ばれるメソッド定義ができます。

複数の外部パッケージを同時使用するときなどにレシーバ追加をしたいときがあるんですが、言語規則のためそのままだと追加できません。

基本的なことからおさらいしつつ対策を考えます。

型定義とレシーバ

適当な型に適当なメソッドを定義しました。

 

型名やフィールド名の最初を大文字にすることでグローバルスコープにできます。

ローカルだけで使ったり、セッターゲッターでやり取りする場合は小文字にするのがよさそうですが、templateのような外部パッケージで使う時に困ることもあるので基本はグローバルでいいと思います。

 

ところで厳密に見るとこのメソッドはおかしいです。

ポインタに対するアクションを定義しているのでなのでm:=&MainType{"main"}としないといけない気がしますが、GOのコンパイラがうまいこと処理してくれます。

つまり逆転しても正常動作します。

とはいえ実情に合わせて使ったほうが良いです。

 

セッターなどを実装する場合にはポインタレシーバでないとうまく動かせないことがあります。これは関数の引数と同じように考えます。

後は呼び出し元がnilでないことだけ注意します。

 

ところで構造体の中身に適当な処理をしたいだけなら普通に関数を使うべきです。

この場合は厳密な型が要求されるので渡す型には注意する。

レシーバは汎用的なインターフェースの実装のために使うものだと思います。

メソッドチェーンが気持ちよすぎてなんでもレシーバにしてしまうことがありますが大体混乱のもとです。

外部パッケージのレシーバ定義

外部パッケージAのインターフェース引数に外部パッケージBの型を渡そうとするときなどにやりたくなります。

具体的にはginのStaticFS()にstatik(http.FileSystem)の型を入れるときなどです。

 

テストとしてサブパッケージを作って読み込みます。

 

ローカルパッケージ以外のレシーバ定義はエラーになります。

 

つまりローカルにそのまま定義しなおせばメソッドを追加できます。

 


コメントを残す

メールアドレスが公開されることはありません。