[Go言語]Interfaceを学ぼう~初級から中級者までの道のり~

こんにちは。KOUKIです。

とあるWeb系企業でエンジニアをやってます。

本記事では、Go言語のInterfaceについて初級者から中級者に上がるために知っておいた方がいいことを記載しました。

Interfaceの理解に少しでも役立ったら幸いです。

Interfaceの基本

Interffaceの基本は、以下を参考にしてください。

Interfaceを使わないバージョン

最初にInterfaceを使わないコードを書いてみましょう。

person構造体を用意し、speakメソッドを定義しました。

そして、main関数からインスタンス化して、処理を呼び出します。

簡単ですね^^

Interfaceを使ったバージョン

次に、Interfaceを使ったバージョンを書いてみましょう。

Interfaceを定義

最初に、Interfaceを定義します。

Go言語の場合は、interfaceキーワードでinterfaceを定義します。

Interfaceを呼び出す

続いて、main関数からinterfaceを呼び出しましょう。

human interfaceを型にしたselfnote変数を定義しました。

その後に、person構造体からインスタンス化したp1を代入してますが、このコード、コンパイルエラーになると思いますか?

実はコンパイルエラーになりません

Go言語では、Interfaceに定義した関数(ここではspeak)と同名のメソッドを定義した構造体は、Interfaceを実装したとみなされます

person構造体は、speakメソッドを実装しているため、human interfaceを実装したと見なされます。よって、selfnote変数にp1変数を代入することが可能になります。

もちろん、speakメソッドをコメントアウトすればエラーになります。

面白いですね!

Interfaceメソッドの呼び出し

次に、person 構造体を持った構造体を定義しましょう。

このコードは、下記のように呼び出します。

selfnote, superSelfnoteをhuman interfaceの型で定義し、それぞれにperson構造体、superman構造体のインスタンスを代入しています。

一度、このソースコードを実行してみましょう。

想定通り、それぞれのメソッドの処理が呼ばれましたね。

定義した型は同じhumanなのに、それぞれのメソッドが呼ばれるのはなんだか不思議な感じがしますね。

応用: interface型の引数

ここでInterfaceの応用的な使い方をみていきましょう。

下記の関数を定義します。

この関数は、human interface型を引数にしています

このような関数を定義すると下記の呼び出し方が可能です。

human interfaceを満たす変数は全てtalk関数に渡せました

逆にいうとhuman interfaceを満たさない変数は渡せないので、speakメソッドを実装した変数のみ引数に指定できる、という制約を作ることができます。

アクセサーを作る

続いて、Interfaceを使ってアクセサーを作成しましょう。

シチュエーション的には、2つのDBが存在するとします。

  1. MongoDB
  2. PostgreSQL

このDBはそれぞれ「save」、「retrieve」というメソッドを持ちDB操作を行います。

そこで、accessor interfaceを介してこれらのメソッドにアクセスできるプログラムを作成します。

前述した通り、関数の型にinterface型を指定するとそのinterfaceのメソッドを実装した構造体の変数しか引数として渡せません

この性質を利用するとアクセサーを作ることができます。

アクセサーを介してでないとDBの操作を行えない、などの制約が作れそうですね^^

アクセサーをカプセル化する

もう少し、アクセサーを改良してみましょう。

先ほど実装したアクセサーをpersonService構造体でカプセル化(カプセル化という用語でいいのか?)します。

このコードは、以下のように使います。

personServiceをインスタンス化するとき、dbm(MongoDB),dbp(Postgres)を渡してますね。

これにより、処理の呼び出し時にDB操作メソッドをインスタンスのメソッドとして呼び出せます

処理の呼び出しがよりシンプルになりましたね!

Interfaceの使用例

Go言語の標準パッケージでもInterfaceはよく使われます。

例えば、ioパッケージのReaderが代表ですね。

このReader interfaceは至る所で使われます。

例えば、osパッケージのCopyメソッドなどがそうです。

Go言語の標準パッケージを眺めてみて、Interfaceの使われ方を学ぶことも有益だと思います^^

まとめ

今回紹介したInterfaceの機能はごく一部です。

Interfaceは汎用性が高いので様々な用途で使われます。

以下の記事でおすすめの使い方を紹介しているので、ぜひご一読ください。

Go言語まとめ

まとめ記事

コメントを残す