在 Go 看 control flow 的輔助函式

fcamel
3 min readOct 13, 2018

--

看 C/C++ code 的時候,我習慣輸出 __FILE__, __LINE__, __FUNCTION__ 幫助看 control flow。透過 C 的巨集,很容易寫出高效率的輔助函式。

我在 Go 寫了類似的函式 Trace()。作法是取 runtime info,效率比 C/C++ 版本差,內容如下:

func Trace(format string, a ...interface{}) { 
function, file, line, _ := runtime.Caller(1)
info := fmt.Sprintf("DEBUG> %s:%d %s:", path.Base(file), line,
runtime.FuncForPC(function).Name())
msg := fmt.Sprintf(format, a...)
fmt.Println(info, msg)
}

使用實例:

  1 package main
2
3 import (
4 "github.com/fcamel/golang-practice/utils"
5 )
6
7 type myType struct {
8 }
9
10 func (t myType) hello() {
11 utils.Trace("")
12 }
13
14 func foo() {
15 utils.Trace("begin")
16 defer utils.Trace("end")
17 bar()
18 }
19
20 func bar() {
21 utils.Trace("Hello %d", 101)
22 var t myType
23 t.hello()
24 }
25
26 func main() {
27 foo()
28 }

執行結果:

$ go run cmd/trace/main.go
DEBUG> main.go:15 main.foo: begin
DEBUG> main.go:21 main.bar: Hello 101
DEBUG> main.go:11 main.myType.hello:
DEBUG> main.go:18 main.foo: end

美中不足的是,從 method 呼叫 Trace() 的時候,無法自動補上 object 的 address。要自己手動寫,像是這樣:

func (t myType) hello() {
utils.Trace("%p", &t)
}

有多個 objects 呼叫一樣函式的時候,會不太方便。或許多研究一下 runtime 的功能,有機會作到?等受不了的時候,再研究看看。

--

--