_file_或_line_在golang中类似

huangapple go评论75阅读模式
英文:

_file_ or _line_ similar in golang

问题

在Go语言中是否有类似于"_file_""_line_"的函数,可以在运行时知道是谁调用了特定的函数?在C语言中,我们有可以作为宏调用的"_file_"行。在Go语言中如何实现这个功能?

英文:

is there any function in go that is similar like "_file_" or "_line_" in go, to know who is calling a specific function during run time? In C we have the "_file_" line that can be called as macros. How to do this in go?

答案1

得分: 19

如果您正在使用log包,您可以指示记录器在条目前添加各种信息的前缀。您可能最感兴趣的是Lshortfile常量,它将导致类似于d.go:23的前缀。另外,还有Llongfile,它会打印文件的完整路径(例如/a/b/c/d.go:23)。

如果您不想使用log包,您也可以使用runtime.Caller(),这是log包在内部使用的方法。它不像C宏那样直接,但您可以将其隐藏在一个函数后面(并指定正确的调用深度)。您可以查看log包的实现方式作为示例(第140行)。

英文:

If you're using the log package, you can instruct the logger to prefix the entries with various information. You'll likely be most interested in the Lshortfile constant, which will result in prefixes along the lines of d.go:23. Alternatively, there is Llongfile which prints the file's full path (such as /a/b/c/d.go:23).

If you don't want to use the log package, you could also use runtime.Caller(), which is what the log package uses internally. It's not as straight forward as the C macros, but you could hide it behind a function (and specify the correct call depth). You can see how the log package is implemented for an example (line 140).

答案2

得分: 14

(1) 编写一个简短的函数来调用runtime.Caller()

(2) 在你想要在运行时访问源代码文件和行号的地方调用该函数。

示例:

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
}

注意:将1传递给Caller(),以便它返回调用file_line()的行号,而不是调用runtime.Caller()的行号。

fmt.Println(file_line())  // 打印该文件和行号。
英文:

(1) Write a brief function that calls runtime.Caller()

(2) Call that function everywhere you want to access the source code file and line number at run time.

Example:

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
}

Note: pass 1 to Caller() so that it returns the number of the line where file_line() is called, instead of where runtime.Caller() is called.

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

答案3

得分: 2

请参考runtimeruntime.debug包,特别是StackPrintStackCaller函数

> Stack将调用goroutine的堆栈跟踪格式化为buf并返回写入buf的字节数。如果alltrue,则在当前goroutine的跟踪之后,Stack会将所有其他goroutine的堆栈跟踪格式化为buf

如果您使用调试信息进行编译,那么这将包含源代码中的行号。

英文:

See the runtime and runtime.debug packages and in particular the Stack, PrintStack or Callerfunctions.

> Stack formats a stack trace of the calling goroutine into buf and returns the number of bytes written to buf. If all is true, Stack formats stack traces of all other goroutines into buf after the trace for the current goroutine.

If you are compiling with debug information, then this will should contain the line number in source

答案4

得分: 0

//import ( "log" "strings" "bytes" "path/filepath" )
func SRC_FILE() string {
var buf bytes.Buffer
log.New(&buf, "", log.Lshortfile).Output(2, "")//2=>CALLER
FILE_LINE := strings.TrimSpace(buf.String())
FILE := strings.TrimRight(FILE_LINE, ":1234567890")
return FILE
}

func SRC_DIR() string {
var buf bytes.Buffer
log.New(&buf, "", log.Llongfile).Output(2, "")//2=>CALLER
FILE_LINE := strings.TrimSpace(buf.String())
FILE := strings.TrimRight(FILE_LINE, ":1234567890")
DIR := filepath.Dir(FILE)
return DIR
}

func main() {
fmt.Println(SRC_FILE())//analogous to FILE
fmt.Println(SRC_DIR()) //analogous to DIR
}

英文:
//import ( "log" "strings" "bytes" "path/filepath" )
func SRC_FILE() string {
	var buf bytes.Buffer
	log.New(&buf, "", log.Lshortfile).Output(2, "")//2=>CALLER 
	__FILE_LINE__ := strings.TrimSpace(buf.String())
	__FILE__ := strings.TrimRight(__FILE_LINE__, ":1234567890")
	return __FILE__
}

func SRC_DIR() string {
	var buf bytes.Buffer
	log.New(&buf, "", log.Llongfile).Output(2, "")//2=>CALLER
	__FILE_LINE__ := strings.TrimSpace(buf.String())
	__FILE__ := strings.TrimRight(__FILE_LINE__, ":1234567890")
	__DIR__ := filepath.Dir(__FILE__)
	return __DIR__
}

func main() {
	fmt.Println(SRC_FILE())//analogous to __FILE__
	fmt.Println(SRC_DIR()) //analogous to __DIR__
}

https://go.dev/play/p/3nvgknX96RO
When you run it on go.dev/play your code is run as prog.go

huangapple
  • 本文由 发表于 2013年7月14日 22:39:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/17640360.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定