1.函数分析
// skip为0的时候表示当前所在的函数,即栈顶,1是从栈顶往下数第二个,以此类推,
// line为执行了所在函数内的哪一行,
// file为函数所在的文件名,
// pc是所在函数的指针,
func Caller(skip int) (pc uintptr, file string, line int, ok bool) {
rpc := make([]uintptr, 1)
n := callers(skip+1, rpc[:])
if n < 1 {
return
}
frame, _ := CallersFrames(rpc).Next()
return frame.PC, frame.File, frame.Line, frame.PC != 0
}
skip是层数,调用Caller函数外层的函数。1代表上次,2代表上上层,一般我们需要定位的也就是行数line跟file文件名
2.运用举例
package main
import (
"fmt"
"runtime"
)
func exe(){
task()
}
func task(){
pc,file,line, ok := runtime.Caller(1)
fmt.Println(pc)
fmt.Println(file)
fmt.Println(line)
fmt.Println(ok)
}
func main() {
task()
exe()
}
3.运行结果分析
skip等于1返回的就是上层的调用所以task函数第20行跟第10行都是调用task的地方
14646342
G:/mycode/go/main/main.go
20
true
14646347
G:/mycode/go/main/main.go
10
true
下面将pc,file,line, ok := runtime.Caller(1)的参数skip1改为2看看结果,能不能打印exe函数的行数
答案是打印了第21行
4.运用在工程中
可以参考上篇文章
统一错误处理
需要跳过两层,查看调用
func HandleInternalError(response *restful.Response, req *restful.Request, err error) {
handle(http.StatusInternalServerError, response, req, err)
}
// HandleBadRequest writes http.StatusBadRequest and log error
func HandleBadRequest(response *restful.Response, req *restful.Request, err error) {
handle(http.StatusBadRequest, response, req, err)
}
func HandleNotFound(response *restful.Response, req *restful.Request, err error) {
handle(http.StatusNotFound, response, req, err)
}
func HandleForbidden(response *restful.Response, req *restful.Request, err error) {
handle(http.StatusForbidden, response, req, err)
}
func HandleUnauthorized(response *restful.Response, req *restful.Request, err error) {
handle(http.StatusUnauthorized, response, req, err)
}
func HandleTooManyRequests(response *restful.Response, req *restful.Request, err error) {
handle(http.StatusTooManyRequests, response, req, err)
}
func HandleConflict(response *restful.Response, req *restful.Request, err error) {
handle(http.StatusConflict, response, req, err)
}