Go言語でインターフェースのメソッドを列挙する

Go 言語のリフレクションで型情報を扱う Type は以下で取得できます。

func TypeOf(i interface{}) Type

引数 i には値を指定する事になりますが、インターフェースの型情報を取得したい場合はどうするのか気になって試してみたところ、以下で取得できました。

インターフェースの型情報を取得
TypeOf( (*対象インターフェース)(nil) ).Elem()

対象とするインターフェースのポインタ型の nil を使って TypeOf を実施した後、Elem ※ を使ってインターフェースの型情報を取得します。

 ※ Elem() で Array, Chan, Map, Ptr, Slice から
    要素の型情報を取得できる

これを利用して、インターフェースのメソッドを列挙するとこのようになります。

sample.go
package main

import (
    "fmt"
    "reflect"
)

type Counter interface {
    Up(v int)
    Down(v int)
    Current() int
    reset()
    end() int
}
// メソッド情報の出力
func printMethods(t reflect.Type) {
    for i := 0; i < t.NumMethod(); i++ {
        fmt.Println("method:", t.Method(i))
    }
}

func main() {
    // Counter インターフェースの型情報を取得
    t := reflect.TypeOf((*Counter)(nil)).Elem()

    printMethods(t)
}
ビルドと実行
> go build sample.go

> sample
method: {Current  func() int <invalid Value> 0}
method: {Down  func(int) <invalid Value> 1}
method: {Up  func(int) <invalid Value> 2}
method: {end main func() int <invalid Value> 3}
method: {reset main func() <invalid Value> 4}

ちなみに、上記コードで t := reflect.TypeOf((Counter)(nil)) のようにすると、t.NumMethod()panic: runtime error: invalid memory address or nil pointer dereference となりました。