如何从代码中获取当前GOPATH

如何从代码中获取当前GOPATH,go,Go,如何从代码块中获取当前的GOPATH runtime只有GOROOT: // GOROOT returns the root of the Go tree. // It uses the GOROOT environment variable, if set, // or else the root used during the Go build. func GOROOT() string { s := gogetenv("GOROOT") if s != "" {

如何从代码块中获取当前的
GOPATH

runtime
只有
GOROOT

// GOROOT returns the root of the Go tree.
// It uses the GOROOT environment variable, if set,
// or else the root used during the Go build.
func GOROOT() string {
    s := gogetenv("GOROOT")
    if s != "" {
        return s
    }
    return defaultGoroot
}
我可以制作一个用
GOPATH
替换
GOROOT
的函数,但是是否有用于此的内置程序?

使用

从文档:

Getenv检索由 钥匙它返回值,如果变量不为空,则该值为空 现在

例如:

package main

import (
    "fmt"
    "os"
    )

func main() {
    fmt.Println(os.Getenv("GOPATH"))
}
更新Go 1.8+

Go 1.8具有通过Go/build导出的默认GOPATH:

package main

import (
    "fmt"
    "go/build"
    "os"
)

func main() {
    gopath := os.Getenv("GOPATH")
    if gopath == "" {
        gopath = build.Default.GOPATH
    }
    fmt.Println(gopath)
}
自Go 1.8以来,有一个:

GOPATH
环境变量指定 工作空间。它默认为一个名为go in your home的目录 目录,因此在Unix上是
$HOME/go
,在Plan 9上是
$HOME/go
,以及 Windows上的
%USERPROFILE%\go
(通常是
C:\Users\YourName\go

这意味着
GOPATH
环境变量不一定设置为任何特定的值

您仍然可以使用
os.Getenv
获取该值,但如果未设置该值,则需要确保使用特定于平台的默认值,例如使用:

你应该使用软件包


今天我为了我正在做的事情而把这件事搞砸了,这比我想象的要烦人得多。最后,在我对它进行的各种测试中,这似乎对我有效(而不是“严格”的测试)

注意,如果GOPATH上列出了多条路径,我决定只使用第1条路径,因为我怀疑很少有人会列出超过1条路径,第一条路径是
go-get
放置源的位置(我猜)。此代码也不考虑路径是否有效


还要注意,要在获得GOPATH后构建文件路径,我必须使用
path/filepath.Join()
not
path.Join()
。如果第一个参数包含\,则前者将在windows上使用\和/或用于其他参数。虽然windows显然可以接受/for路径,但所有类似my PATH和GOPATH的环境变量都是使用windows的普通\来编写的
path.Join()
used/,生成无效路径。

在go 1.8中,GOPATH env变量是可选的。如果用户没有呢?有没有办法得到默认值?我认为go运行时应该有办法获得gopath,让go自己为您解决。@tothemario我给出了一个答案,告诉您如何从go 1.8中获得有效的
gopath
。不过,我同意理想情况下,运行时应该提供一种方法,使用Go 1.8默认Go path实现中的代码获取用户的
GOPATH
@tothemario更新答案。别忘了GOPATH可以列出多个路径,并用操作系统的路径分隔符分隔。这有点过分。我们可以使用Go自己源代码中的代码来获得默认的Go路径。看@codefank,当然有更简单的方法,你的答案也是有效的。我喜欢的是,当有疑问时,它会尝试多种方法来查找主目录,如果都失败了,它实际上会返回一个错误。因此,此代码的用户可以返回有意义的错误消息。如果您只是返回一个空字符串,用户必须检查它是否为空。如果他们忽略了这一点,在某些边缘情况下,这可能会导致意外的行为或奇怪的错误。go homedir对于查找home dir非常有用。但如果Go本身使用defaultGOPATH函数,那么处理Go构建代码本身不处理的边缘情况又有什么意义呢。总之,让用户决定他们最喜欢什么:)
package main

import (
        "fmt"
        "log"
        "os"

        "github.com/mitchellh/go-homedir"
)

func main() {
        p, err := gopath()
        if err != nil {
                log.Fatalf("Error finding GOPATH: %v", err)
        }

        fmt.Println(p)
}

func gopath() (string, error) {
        s := os.Getenv("GOPATH")
        if s != "" {
                return s, nil
        }
        return homedir.Expand("~/go")
}
package main

import (
    "fmt"
    "go/build"
)

func main() {
    fmt.Println(build.Default.GOPATH)
}
goPath := strings.Split(os.Getenv("GOPATH"), string(os.PathListSeparator))
if len(goPath) == 0 {
    goPath = append(goPath, build.Default.GOPATH)
} else if goPath[0] == "" {
    goPath[0] = build.Default.GOPATH
}