是否有可能获得在Golang中调用代码的文件名?

时间:2017-11-10 08:42:41

标签: file go

我能够获得当前目录的完整路径,现在我想创建一个函数来读取或获取执行代码的文件名。我能够获取文件名,但它返回编写代码的原始文件名:

func GetFileName() string {
    _, fpath, _, ok := runtime.Caller(0)
    if !ok {
        err := errors.New("failed to get filename")
        panic(err)
    }
    filename := filepath.Base(fpath)
    // remove extension
    filename = removeExtension(filename)
    return filename + ".log"
}

我想要做的是获取执行代码的当前fileName,如:

我创建了app.go

package my

function getCurrentFileName() string {
    // some code here that will return the filename where this code is executed.
}

然后当我在不同位置的getCurrentFileName()之类的其他文件中调用hello.go时。它将返回hello.go

我被困在这里一段时间并寻找答案。

2 个答案:

答案 0 :(得分:4)

基本上这是你告诉/传递给https://firebase.google.com/docs/reference/android/com/google/firebase/auth/AdditionalUserInfo.html#isNewUser()的内容:在返回条目之前要跳过的堆栈条目数。

如果您在代码中传递Test if given int is 0, if so print "Blast off". if not print the int and call the same function with int-1 call function with your user input integer. ,则表示返回调用0的堆栈条目(其中称为runtime.Caller())。传递runtime.Caller()将跳过您的函数,并返回调用函数的函数:

1

示例调用包含此函数的函数(在我的示例中为pc, file, line, ok := runtime.Caller(1) if ok { fmt.Printf("Called from %s, line #%d, func: %v\n", file, line, runtime.FuncForPC(pc).Name()) } ):

subplay.A()

输出:

 7   func main() {
 8      // Comment line
 9      subplay.A()
10   }

我们看到代码从Called from /home/icza/gows/src/play/play.go, line #9, func: main.main 包的函数play.go打印main()在第9行调用我们的函数。

答案 1 :(得分:0)

这个辅助函数可以提供这些信息:

func Here(skip ...int) (string, string, int, error) {
    sk := 1
    if len(skip) > 0 && skip[0] > 1 {
        sk = skip[0]
    }
    var pc uintptr
    var ok bool
    pc, fileName, fileLine, ok := runtime.Caller(sk)
    if !ok {
        return "", "", 0, fmt.Errorf("N/A")
    }
    fn := runtime.FuncForPC(pc)
    name := fn.Name()
    ix := strings.LastIndex(name, ".")
    if ix > 0 && (ix+1) < len(name) {
        name = name[ix+1:]
    }
    funcName := name
    nd, nf := filepath.Split(fileName)
    fileName = filepath.Join(filepath.Base(nd), nf)
    return funcName, fileName, fileLine, nil
}

skip参数是我们需要上调的呼叫者帧数(呼叫者链)。