2013-07-14 3 views
8

Gibt es irgendeine Funktion in go, die ähnlich ist wie "_file_" oder "_line_" in gehen, um zu wissen, wer eine bestimmte Funktion während der Laufzeit aufruft? In C haben wir die "_file_" Zeile, die als Makros aufgerufen werden kann. Wie geht das in gehen?_file_ oder _line_ ähnlich in golang

+1

[Siehe auch] (http://stackoverflow.com/q/17543546/720999) – kostix

Antwort

14

Wenn Sie das log Paket verwenden, können Sie den Logger prefix the entries with various information anweisen. Sie werden wahrscheinlich am meisten an der Konstante Lshortfile interessiert sein, die zu Präfixen entlang der Linien führt. Alternativ gibt es Llongfile, die den vollständigen Pfad der Datei (wie /a/b/c/d.go:23) druckt. Wenn Sie das Paket log nicht verwenden möchten, können Sie auch runtime.Caller() verwenden, was das Protokollpaket intern verwendet. Es ist nicht so einfach wie die C-Makros, aber Sie können es hinter einer Funktion verbergen (und die korrekte Aufruftiefe angeben). Sie können see how the log package is implemented für ein Beispiel (Zeile 140).

+3

Um explizite: 'log.SetFlags (log.Lshortfile)' und dann 'log.Println (" Fehler! ")' wird "myfile.go: 8: Fehler!" – 425nesp

2

Siehe runtime und runtime.debug Pakete und insbesondere die Stack, PrintStack oder Callerfunctions.

Stack formatiert einen Stack-Trace der aufrufenden Goroutine in buf und gibt die Anzahl der auf buf geschriebenen Bytes zurück. Wenn alles wahr ist, stapelt das Stack-Format die Spuren aller anderen Goroutines nach der Trace für die aktuelle Goroutine in buf.

Wenn Sie mit Debug-Informationen kompilieren, dann ist dies die Zeilennummer in der Quelle enthalten sollte

7

(1) Schreiben Sie eine kurze Funktion, die runtime.Caller()

(2) Rufen Sie diese Funktion überall wollen Sie den Quellcode-Datei und die Zeilennummer zur Laufzeit für den Zugriff auf Anrufe.

Beispiel:

import "runtime" 

func file_line() string { 
    _, fileName, fileLine, ok := runtime.Caller(1) 
    var s string 
    if ok { 
     s = fmt.Sprintf("%s:%d", fileName, fileLine) 
    } else { 
     s = "" 
    } 
    return s 
} 

Anmerkung: Durchgang 1 zu Caller() so, dass sie die Nummer der Zeile zurückkehrt, wo file_line() aufgerufen wird, statt wo runtime.Caller() aufgerufen wird.

fmt.Println(file_line()) // Prints this file and line number.