Go에서 함수 이름을 얻는 방법은 무엇입니까?


101

함수가 주어지면 그 이름을 얻을 수 있습니까? 말하다:

func foo() {
}

func GetFunctionName(i interface{}) string {
    // ...
}

func main() {
    // Will print "name: foo"
    fmt.Println("name:", GetFunctionName(foo))
}

나는 runtime.FuncForPC 가 도움이 될 것이라고 들었지만 그것을 사용하는 방법을 이해하지 못했습니다.

답변:


187

내 질문에 답해 주셔서 죄송하지만 해결책을 찾았습니다.

package main

import (
    "fmt"
    "reflect"
    "runtime"
)

func foo() {
}

func GetFunctionName(i interface{}) string {
    return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
}

func main() {
    // This will print "name: main.foo"
    fmt.Println("name:", GetFunctionName(foo))
}

2
이것이 작동하는 것처럼 보이지만 여기에 약간의주의가 필요할 수 있습니다. .Pointer ()에 대한 문서에 "v의 종류가 Func이면 반환 된 포인터는 기본 코드 포인터이지만 단일 함수를 고유하게 식별하기에 충분하지는 않습니다. v가 nil func 값인 경우에만 결과가 0이라는 것을 보장합니다. "
jochen

1
@jochen은 "단일 함수가 아님"이 거짓 긍정 (즉, 다른 함수의 포인터)을 반환 할 수 있음을 의미합니까?
themihai

1
@themihai 모르겠습니다. 제가 인용 한 문장은 golang.org/pkg/reflect/#Value.Pointer의 모든 문서 입니다. 그러나 인용문은 다른 기능에 대해 동일한 포인터를 얻을 수 있음을 나타내는 것 같습니다. 이 경우 GetFunctionName다른 함수에 대해 동일한 이름을 반환 할 수 있습니까?
jochen

3
@jochen 나는 이것이 클로저와 관련이 있다고 생각합니다. 동일한 기본 기능을 가진 두 개의 클로저를 생성하면 닫히는 값이 다르더라도 동일합니다.
Alex Guerra

9

파일 이름과 줄 번호를 기록하기 때문에 정확히 원하는 것은 아니지만 "런타임"패키지를 사용하여 Tideland Common Go 라이브러리 ( http://tideland-cgl.googlecode.com/ ) 에서 수행하는 방법은 다음과 같습니다.

// Debug prints a debug information to the log with file and line.
func Debug(format string, a ...interface{}) {
    _, file, line, _ := runtime.Caller(1)
    info := fmt.Sprintf(format, a...)

    log.Printf("[cgl] debug %s:%d %v", file, line, info)

1
정말 도움이되지 않습니다. 호출 스택에 대한 정보가 아니라 주어진 함수에 대한 정보를 얻을 필요가 없습니다. 함수 참조 (가능하다면)가 주어진 해당 PC를 얻는 방법을 알고 있다면 질문에 답할 수 있다고 생각합니다.
moraes 2011-08-13
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.