2012-05-24 20 views
11

Bir işlevin adını almak için Go'nun yansıma sistemini kullanmaya çalışıyorum ama türünde Ad yöntemini çağırırken boş bir dize alıyorum. Beklenen davranış bu mu?Golang'da yansımayı kullanarak işlevin ismini alın Get

Bu, sorunu yaklaşım ne basit bir örnek aşağıda verilmiştir:

package main 

import "fmt" 
import "reflect" 

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

Bana öyle geliyor ki, ana tip "fonksiyon" dır. Bir isim olarak ne beklerdin? –

+0

Bu çok önemli bir nokta. Kod örneği, muhtemelen işe yaramaz, ama sorunun adı geçerli olduğunu düşünüyorum. – Laserallan

cevap

20

çözelti *Func döner FuncForPc kullanmaktır.

Bu "main.main" döndürür: Eğer "main" istiyorsanız

package main 

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


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

, sadece simgeleştirir.

+0

Teşekkürler. Bu problemi çözdü! – Laserallan

+9

Veya yansıtmasız, pc, _, _, _: = runtime.Caller (0) fmt.Println ("İşlev adı:" + runtime.FuncForPC (pc) .Name()) – Sonia

+0

İlginç. Ama OP'nin herhangi bir işlevle daha genel bir çözüm aradığını varsayıyordum. –

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()) 
} 

Çıktı:

fonksiyonun Adı: main.main fonksiyonunun

Adı: main.main fonksiyonunun
Adı: main: fonksiyonunun
Adı main.x. y
İşlev adı: main.z

+0

Şahsen, çözümünüzü (ya da @ Koala3'ün uzantısını kendi çözümünüzde) tercih ederim; bunun nedeni, çalışma zamanı çağrılarının başka bir yerde 'güvenli bir şekilde' dağıtılabilen bir işlev içinde kapsüllenmesine izin vermesidir; Git çalışma zamanı bir nedenden dolayı değişirse, tüm kodun sadece bir noktada değiştirilmesi gerekir. Ayrıca, yansıma yapmak kaçınılmaz bir hile, aferin! :) –

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

Paket ismini fonksiyon ismiyle tutmanın avantajı, elbette, farklı paketlerde aynı isimde birkaç fonksiyona sahip olmanızın mümkün ... ve sonra hangisinin olduğuna dair bir fikriniz yok :) Aslında, Bu cevabı SO için aramamın ana nedeni, hangi işlevlerimin bir hataya neden olduğundan emin olmadığım ve işlev adının yanı sıra, doğru paket adını takip etmem gerektiğiydi ... çözümünüzü çalışmak için "dizeleri" ve "dosya yolunu" içe aktarın! –

İlgili konular