Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

interface

インターフェースは、型が持つべきメソッドの集合を定義します。Goのインターフェースは暗黙的に実装され、明示的な宣言は不要です。

構文
// インターフェースを定義します。
type インターフェース名 interface {
    メソッド名(引数) 戻り値型
}

// 空インターフェース(any)はすべての型を受け入れます。
var v any = "Hello"
var v interface{} = 42
インターフェース一覧
構文・型概要
type I interface { M() }メソッド『M()』を要求するインターフェースを定義します。
any『interface{}』の組み込みエイリアスです(Go 1.18+)。すべての型を受け入れます。
interface{}メソッドが0個の空インターフェースです。すべての型が実装しています。
型アサーション: v.(T)インターフェース値を具体的な型に変換します。変換に失敗するとパニックが発生します。
型アサーション: v, ok := v.(T)変換に失敗しても『ok』が『false』になるだけでパニックは発生しません。
型スイッチ: switch v.(type)インターフェース値の具体的な型によって処理を分岐させます。
サンプルコード
package main

import (
    "fmt"
    "math"
)

// Shapeインターフェースを定義します。
type Shape interface {
    Area() float64
    Perimeter() float64
}

// Circle構造体を定義します。
type Circle struct {
    Radius float64
}

// CircleがShapeインターフェースを暗黙的に実装します。
func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

func (c Circle) Perimeter() float64 {
    return 2 * math.Pi * c.Radius
}

// Rectangle構造体を定義します。
type Rectangle struct {
    Width, Height float64
}

// RectangleもShapeインターフェースを実装します。
func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

func (r Rectangle) Perimeter() float64 {
    return 2 * (r.Width + r.Height)
}

// インターフェース型を引数に取る関数です。
func printShape(s Shape) {
    fmt.Printf("面積: %.2f, 周囲: %.2f\n", s.Area(), s.Perimeter())
}

func main() {
    c := Circle{Radius: 5}
    r := Rectangle{Width: 3, Height: 4}

    printShape(c) // CircleはShapeを満たします。
    printShape(r) // RectangleもShapeを満たします。

    // 空インターフェースはすべての型を受け入れます。
    var anything any = "文字列"
    fmt.Println(anything) // 『文字列』と出力されます。
    anything = 123
    fmt.Println(anything) // 『123』と出力されます。

    // 型アサーションで具体的な型に変換します。
    var s Shape = Circle{Radius: 3}
    if circle, ok := s.(Circle); ok {
        fmt.Println("半径:", circle.Radius) // 『半径: 3』と出力されます。
    }

    // 型スイッチで型ごとに処理を分岐します。
    values := []any{42, "hello", true, 3.14}
    for _, v := range values {
        switch val := v.(type) {
        case int:
            fmt.Printf("整数: %d\n", val)
        case string:
            fmt.Printf("文字列: %s\n", val)
        default:
            fmt.Printf("その他: %v\n", val)
        }
    }
}
概要

Goのインターフェースは他の言語と異なり、型がインターフェースを実装することを明示的に宣言しません。型が必要なメソッドをすべて実装していれば自動的にそのインターフェースを満たします。これを「ダックタイピング」と呼びます。

型アサーション『v.(T)』は変換に失敗するとパニックを引き起こします。安全に変換するには『v, ok := v.(T)』の2値形式を使用してください。

空インターフェース『any』(旧『interface{}』)はすべての型を格納できますが、使用時は型アサーションや型スイッチで具体的な型に変換する必要があります。型の安全性を保つため、可能な限り具体的なインターフェースを定義することを推奨します。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。