質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.62%

  • Go

    480questions

    Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Go言語のinterfaceの存在意義

受付中

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 849

temppp

score 2

質問内容

go言語のinteraceの存在意義がわかりません。

以下のサイトにgo言語のinterfaceについての説明が書かれていますが、
なぜこのように面倒なことをしなければならないのでしょうか。
https://go-tour-jp.appspot.com/methods/10
http://dev.classmethod.jp/go/golang-6/

おそらく使いこなすと便利なのかもしれないのですが、
自分で実装する際の必要性がいまいちわかりません。

教えていただたきたいこと

・interfaceを使わなければ実現できないことはあるのでしょうか。
・具体的な便利な利用方法を教えてください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+8

まずこのソースを見て下さい。

package main

import (
    "fmt"
)

type Foo struct{}

func (f *Foo) Name() string {
    return "Foo"
}

type Bar struct{}

func (b *Bar) Name() string {
    return "Bar"
}

type Named interface{ 
    Name() string
}

func CallName(named Named) {
    fmt.Println(named.Name())
}

func main() {
    foo := new(Foo)
    bar := new(Bar)

    CallName(foo)
    CallName(bar)
}

CallName は Foo および Bar どちらの型も受け取れます。継承関係はありませんが、Name() というメソッドがある事だけが型の拘束になります。
この様に、同一の特徴を持った値(この場合 foo もしくは bar)を共通的に取扱いたい場合に interface を用います。

これを Named を使わずやろうと思うとそれぞれの型を引数に持った CallNameFoo もしくは CallNameBar を実装する必要があります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

interface{メソッド}と書くとそのメソッドを実装した変数を格納できるようになりますが、interface{}と書くとなにもメソッドを実装していなくても格納できます。つまり、どんな型のどんな値でも格納できます。
(メソッドを実装する場合については他の回答者さんが既に書かれているので省略します)

https://github.com/golang/go/blob/master/src/fmt/print.go#L630

githubのgolangのfmtパッケージからPrintなどの実装を見ることができます。
どんな型の変数を渡しても適切に表示してくれるのは、このinterface{}型があるからです。
特殊なswitch文を使って型によって処理を分けることができます。

・interfaceを使わなければ実現できないことはあるのでしょうか。 

例えば、fmt.PrintBool() fmt.PrintInt64()のようにすべてメソッドを分ければinterfaceがなくてもなんとかなります。
つまり実現できることが増えるかどうかというと微妙ですが、確実にメソッドを実装させることによってプログラミングをしやすくすることや、型を曖昧に扱えることで処理をだいぶ短く書けるなどのメリットがあります。

・具体的な便利な利用方法を教えてください。

https://play.golang.org/p/AcgSY04_io
switch i.(type){}で処理を分けたり、
i.(int)のようにして型アサート(型変換のinterfaceバージョンの呼称)ができたりします。
これを使って、簡単に型別の処理を書くことができます。
自分はjsonの解析でよく使います。
Qiita golangでのjsonのデコード

A Tour of Goでも有用な使い方が説明されていますし、もしやってなければやってみてはいかがでしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/10 10:54

    type switch は代入して使うと case 先へ変換しなくて良くなるので便利ですよ。 https://play.golang.org/p/mVz3BR0cAY

    キャンセル

  • 2017/01/10 17:01

    おーこれは知りませんでした
    活用させていただきます

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Go

    480questions

    Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。