2013-07-09 97 views
5

是否可以獲取從調用範圍返回函數的行號?獲取返回函數的行號

例子:

func callee() error { 
    if cond { 
    return errors.New("whoops!") 
    } 
    return nil 
} 

func caller() { 
    // Possible to retrieve the line number of callee return here? 
    callee() 
} 

我認爲這是不可能的,因爲它應該從棧中已被刪除,但也許它仍然緩存的地方?

用例是我有一個HTTP處理程序,我想記錄返回錯誤的行和文件名,而不必亂丟代碼。

回答

7

AFAIK,不可能自動獲取執行最後一次退貨的行。

然而,用小幫手可以有:

package main 

import (
     "fmt" 
     "runtime" 
) 

func here(s string, args ...interface{}) error { 
     _, fname, fline, _ := runtime.Caller(1) 
     h := fmt.Sprintf("%s:%d: ", fname, fline) 
     return fmt.Errorf(h+s, args...) 
} 

func foo(i int) error { 
     if i == 2 { 
       return here("cannot handle %d", i) // line 16 
     } 

     if i%3 == 0 { 
       return here("also cannot handle %d", i) // line 20 
     } 

     return nil 
} 

func main() { 
     fmt.Println(foo(2)) 
     fmt.Println(foo(3)) 
     fmt.Println(foo(4)) 
} 

Playground


輸出:

/tmpfs/gosandbox-92c2a0f2_32bdf9d9_3c7d2a0a_80ba8510_f68d9721/prog.go:16: cannot handle 2 
/tmpfs/gosandbox-92c2a0f2_32bdf9d9_3c7d2a0a_80ba8510_f68d9721/prog.go:20: also cannot handle 3 
<nil> 
+1

+1我只是寫了一些類似的代碼,並即將發佈它作爲答案,只是看到不再有任何需要。 –

+0

是的,我已經考慮過包裝功能選項。如果看起來沒有更好的選擇,那麼會使用它。 –