गो में एक फ़ंक्शन का नाम कैसे प्राप्त करें?


101

एक फ़ंक्शन को देखते हुए, क्या इसका नाम प्राप्त करना संभव है? कहते हैं:

func foo() {
}

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

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

मुझे बताया गया था कि रनटाइम। 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
जब यह काम करने लगता है, तो यहां कुछ देखभाल की आवश्यकता हो सकती है: प्रलेखन के लिए। पॉइंटर () में कहा गया है कि "यदि v का किड फंक है, तो लौटा हुआ पॉइंटर एक अंतर्निहित कोड पॉइंटर है, लेकिन जरूरी नहीं कि किसी एकल फ़ंक्शन को विशिष्ट रूप से पहचाने।" गारंटी यह है कि परिणाम शून्य है और केवल अगर v एक शून्य दुर्गंध मूल्य है। "
जॉचेन

1
@jochen "एक भी दुर्गंध नहीं" का मतलब है कि यह झूठी सकारात्मक (यानी एक अलग कार्य के सूचक) वापस कर सकता है?
थीमिहाई

1
@themihai मुझे नहीं पता, मैंने जो वाक्य उद्धृत किया है, वह सभी golang.org/pkg/reflect/#Value.Pointer पर डॉक्स है । लेकिन उद्धरण से लगता है कि एक ही सूचक को विभिन्न कार्यों के लिए मिल सकता है, है ना? और अगर यह मामला है, तो GetFunctionNameविभिन्न कार्यों के लिए एक ही नाम वापस आ सकता है?
जौकेन

3
@jochen मुझे लगता है कि इसे क्लोजर के साथ करना होगा; यदि आप दो क्लोजर बनाते हैं, जिसमें एक ही अंतर्निहित फ़ंक्शन है, तो वे समतुल्य होंगे भले ही वे जिस मान को बंद करते हैं वह अलग हो।
एलेक्स गुएरा

9

वास्तव में आप जो चाहते हैं, वह नहीं, क्योंकि यह फ़ाइल नाम और लाइन नंबर को लॉग करता है, लेकिन यहां बताया गया है कि मैं "रनटाइम" पैकेज का उपयोग करते हुए अपनी टिडलैंड कॉमन गो लाइब्रेरी ( 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
यह वास्तव में मदद नहीं करता है। मुझे कॉल स्टैक के बारे में जानकारी प्राप्त करने की आवश्यकता नहीं है, लेकिन किसी दिए गए फ़ंक्शन के बारे में। मेरा मानना ​​है कि प्रश्न का उत्तर दिया जाएगा यदि मुझे पता था कि संबंधित पीसी को फ़ंक्शन संदर्भ कैसे दिया जाए (यदि यह संभव है)।
मोरा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.