Goで呼び出し元のメソッド名を取得する

Perlだとcallerで呼び出し元のモジュール名やメソッド名が取得できるが、Goでもできるのか?

と思って調べてみた。

コード

package main

import (
	"log"
	"runtime"
)

type Hoge struct {
	name string
}

func (h *Hoge) Print() {
	Log(h.name)
}

func Log(data string) {

	pc, file, line, _ := runtime.Caller(1)
	f := runtime.FuncForPC(pc)
	log.Printf("\ncall:%s\ndata:%s\nfile:%s:%d\n", f.Name(), data, file, line)
}

func main() {
	h := &Hoge{
		name: "hoge hoge",
	}

	h.Print()

	Log("foooo")
}


結果

2009/11/10 23:00:00
call:main.(*Hoge).Print
data:hoge hoge
file:/tmp/sandbox143129349/main.go:13
2009/11/10 23:00:00
call:main.main
data:foooo
file:/tmp/sandbox143129349/main.go:30

解説

runtime.Caller()

で呼び出し元の深さ(0だと自身のメソッドになる)を指定でき、

  • 呼び出し元のPtr
  • ファイル名
  • 行数
  • 呼び出し元が存在するかどうか

が取得できる

ある程度深い場合は返り値のok boolを使って値があるかどうかをチェックする必要がある

runtime.FuncForPC(pc)

でpcの関数情報が取得できる

参考URL