2012-05-24 3 views
11

Go의 반사 시스템을 사용하여 함수의 이름을 검색하려고했지만 유형에 Name 메서드를 호출 할 때 빈 문자열이 나타납니다. 이것은 예상 된 행동입니까?Golang에서 리플렉션을 사용하여 함수 이름 가져 오기

이 내가 문제를 접근하는 방법의 간단한 예는 다음과 같습니다

package main 

import "fmt" 
import "reflect" 

func main() { 
    typ := reflect.TypeOf(main) 
    name := typ.Name() 
    fmt.Println("Name of function" + name) 
} 
+1

메인의 유형은'function'입니다. 이름으로 무엇을 기대합니까? –

+0

그게 중요한 포인트입니다. 코드 예제가 제대로 작동하지 않아야하지만 질문의 이름이 유효하다고 생각합니다. – Laserallan

답변

20

솔루션은 *Func 반환 FuncForPc을 사용하는 것입니다.

"main.main" 반환 : 당신이 "main"을 원하는 경우에

package main 

import "fmt" 
import "reflect" 
import "runtime" 


func main() { 
    name := runtime.FuncForPC(reflect.ValueOf(main).Pointer()).Name() 
    fmt.Println("Name of function : " + name) 
} 

, 그냥 토큰 화.

+0

감사. 이것은 문제를 해결했습니다! – Laserallan

+9

또는 pc, _, _, _ : = runtime.Caller (0) fmt.Println ("함수 이름 :"+ runtime.FuncForPC (pc).()) – Sonia

+0

흥미 롭습니다. 그러나 나는 OP가 어떤 일반적인 기능과 함께보다 일반적인 해결책을 찾고 있다고 가정하고있었습니다. –

25
package main 

import "fmt" 
import "runtime" 

func main() { 
    pc, _, _, _ := runtime.Caller(0) 
    fmt.Println("Name of function: " + runtime.FuncForPC(pc).Name()) 
    fmt.Println() 

    // or, define a function for it 
    fmt.Println("Name of function: " + funcName()) 
    x() 
} 

func funcName() string { 
    pc, _, _, _ := runtime.Caller(1) 
    return runtime.FuncForPC(pc).Name() 
} 

func x() { 
    fmt.Println("Name of function: " + funcName()) 
    y() 
} 

func y() { 
    fmt.Println("Name of function: " + funcName()) 
    z() 
} 
func z() { 
    fmt.Println("Name of function: " + funcName()) 
} 

출력 :

기능의 이름 : main.main 기능의

이름 : main.main 기능의
이름 : 주 : 기능의
이름 main.x. y
기능 이름 : main.z

+0

필자는 개인적으로 솔루션 (또는 자신의 솔루션에 대한 @ Koala3의 확장)을 선호합니다. 주로 런타임에서 호출을 다른 위치에 '안전하게'배포 할 수있는 함수 내에 캡슐화 할 수 있기 때문입니다. Go Runtime이 어떤 이유로 변경된 경우 전체 코드를 한 지점에서만 변경해야합니다. 또한, 반사를 피하는 것은 깔끔한 트릭, 잘 했어! :) –

2
import runtime 

func funcName() string { 
    pc, _, _, _ := runtime.Caller(1) 
    nameFull := runtime.FuncForPC(pc).Name() // main.foo 
    nameEnd := filepath.Ext(nameFull)   // .foo 
    name := strings.TrimPrefix(nameEnd, ".") // foo 
    return name 
} 
+0

패키지 이름을 함수 이름으로 유지하는 이점은 물론 여러 패키지에서 같은 이름을 가진 여러 함수를 가질 수 있다는 것입니다. 그리고 나서 어떤 코드인지는 알지 못합니다 :) 실제로, 나에 대한 대답을 찾는 주된 이유는 어떤 함수가 오류를 일으키는 지 확신 할 수 없었기 때문이며 함수 이름 외에도 정확한 패키지 이름을 추적해야했습니다. 당신의 솔루션이 잘 작동하도록'strings'와'filepath'를 가져 오십시오! –

관련 문제