如何获取当前包的名称?

Kam*_*zic 16 go

有没有办法让运行时获得当前包的名称?

package main

import "fmt"

func main() {
    pkgName := {some magic here:)}
    fmt.Println(pkgName)
}
Run Code Online (Sandbox Code Playgroud)

......结果应该是"主要的"

现在我正在使用常数:

package main

import "fmt"
const (
    pkgName = "main"
)

func main() {
    fmt.Println(pkgName)
}
Run Code Online (Sandbox Code Playgroud)

但我很好奇你是否可以避免这种情况

Mar*_*arc 22

没有提供您正在寻找的功能的运行时反射方法或功能.

我能找到的最接近的是:

package main

import (
    "azul3d.org/lmath.v1"
    "fmt"
    "reflect"
)

type Empty struct{}

func main() {
    fmt.Println(reflect.TypeOf(Empty{}).PkgPath())
    fmt.Println(reflect.TypeOf(lmath.Vec3{0, 0, 0}).PkgPath())
}
Run Code Online (Sandbox Code Playgroud)

这将输出:

main
azul3d.org/lmath.v1
Run Code Online (Sandbox Code Playgroud)

您还可以读取文件的第一行并删除"package"子字符串.(不确定这是不是最好的主意)

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("so.go")
    if err != nil {
        panic(err)
    }
    r := bufio.NewReader(file)
    line, _, err := r.ReadLine()
    if err != nil {
        panic(err)
    }
    packageName := bytes.TrimPrefix(line, []byte("package "))
    fmt.Println(string(packageName))
}
Run Code Online (Sandbox Code Playgroud)


the*_*mue 22

这是我的记录器包的一部分.它检索有关日志记录函数调用者的信息,以便稍后在输出中显示它.

func retrieveCallInfo() *callInfo {
    pc, file, line, _ := runtime.Caller(2)
    _, fileName := path.Split(file)
    parts := strings.Split(runtime.FuncForPC(pc).Name(), ".")
    pl := len(parts)
    packageName := ""
    funcName := parts[pl-1]

    if parts[pl-2][0] == '(' {
        funcName = parts[pl-2] + "." + funcName
        packageName = strings.Join(parts[0:pl-2], ".")
    } else {
        packageName = strings.Join(parts[0:pl-1], ".")
    }

    return &callInfo{
        packageName: packageName,
        fileName:    fileName,
        funcName:    funcName,
        line:        line,
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,它也会返回包名称.


Ros*_*her 6

要可靠地获取包名称,可以使用go编译器的解析器来仅解析package子句.

import (
    "fmt"
    "go/ast"
    "go/parser"
    "go/token"
)

func packageName(file string) (string, error) {
    fset := token.NewFileSet()

    // parse the go soure file, but only the package clause
    astFile, err := parser.ParseFile(fset, l.path, nil, parser.PackageClauseOnly)
    if err != nil {
        return "", err
    }

    if astFile.Name == nil {
        return "", fmt.Errorf("no package name found")
    }

    return astFile.Name.Name, nil
}
Run Code Online (Sandbox Code Playgroud)

  • `l.path` 从哪里来?它不存在! (2认同)
  • 假设程序源本身可用。如果仅将二进制文件复制到另一台计算机上会发生什么? (2认同)