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

huangapple go评论74阅读模式
英文:

How to get current GOPATH from code

问题

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

runtime只有GOROOT

// GOROOT返回Go树的根目录。
// 如果设置了GOROOT环境变量,则使用该变量,
// 否则使用Go构建期间使用的根目录。
func GOROOT() string {
    s := gogetenv("GOROOT")
    if s != "" {
        return s
    }
    return defaultGoroot
}

我可以创建一个将GOROOT替换为GOPATH的函数,但是否有内置函数可以实现这个功能?

英文:

How do I get the current GOPATH from a block of code?

runtime only has 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
}

I could make a function that has GOROOT replaced with GOPATH, but is there a buildin for this?

答案1

得分: 32

使用 os.Getenv

从文档中可以看到:

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)
}
英文:

Use os.Getenv

From docs:

> Getenv retrieves the value of the environment variable named by the
> key. It returns the value, which will be empty if the variable is not
> present.

Example:

package main

import (
	"fmt"
	"os"
	)

func main() {
	fmt.Println(os.Getenv("GOPATH"))
}

Update for Go 1.8+

Go 1.8 has default GOPATH exported via go/build:

package main

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

func main() {
	gopath := os.Getenv("GOPATH")
	if gopath == "" {
		gopath = build.Default.GOPATH
	}
	fmt.Println(gopath)
}

答案2

得分: 13

你应该使用go/build包。

package main

import (
    "fmt"
    "go/build"
)

func main() {
    fmt.Println(build.Default.GOPATH)
}
英文:

You should use go/build package.

package main

import (
	"fmt"
	"go/build"
)

func main() {
	fmt.Println(build.Default.GOPATH)
}

答案3

得分: 1

我今天在处理一个我正在工作的项目时遇到了一些问题,比我预期的要烦人。最后,在我进行的各种测试中,这段代码似乎对我有效(并不是“严格”的测试)。

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
}

请注意,如果在GOPATH中列出了多个路径,我决定只使用第一个路径,因为我怀疑很少有人会列出多个路径,而第一个路径应该是go get放置源代码的位置(我猜的)。此代码还没有考虑路径是否有效。

还请注意,在获取GOPATH后构建文件路径时,我必须使用path/filepath.Join()而不是path.Join()。前者将在Windows上使用\,如果第一个参数包含\,则使用/。尽管Windows显然可以接受/作为路径,但我所有的PATH和类似GOPATH的环境变量都是使用Windows的正常\编写的。path.Join()使用/,会生成一个无效的路径。

英文:

I was messing with this today for something I am working on, and it was more annoying than I'd have expected. In the end, this seemed to work for me in the various tests I did on it (not 'rigorous' tests).

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
}

Note that I decided to use only the 1st path if multiple paths are listed on GOPATH, as I suspect few will have more than 1 path listed, and the first would be where go get puts the source (I guess). This code also does not account for if the paths are valid or not.

Also note that to build a file path after getting the GOPATH, I had to use path/filepath.Join() not path.Join(). The former will use \ on windows if the first arg contains , and / for others. Although windows can accept / for paths apparently, all of my PATH and GOPATH-like environmental variables are written with the normal \ of windows. path.Join() used /, producing an invalid path.

答案4

得分: 0

自Go 1.8版本以来,有一个默认的GOPATH(https://golang.org/doc/code.html#GOPATH):

GOPATH环境变量指定了你的工作空间的位置。它默认为一个名为go的目录,位于你的主目录下,因此在Unix上为$HOME/go,在Plan 9上为$home/go,在Windows上为%USERPROFILE%\go(通常为C:\Users\YourName\go)。

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

你仍然可以使用os.Getenv来获取该值,但是如果它没有被设置,你需要确保使用特定于平台的默认值,例如使用mitchellh/go-homedir

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")
}
英文:

Since Go 1.8, there is a default GOPATH:

> The GOPATH environment variable specifies the location of your
> workspace. It defaults to a directory named go inside your home
> directory, so $HOME/go on Unix, $home/go on Plan 9, and
> %USERPROFILE%\go (usually C:\Users\YourName\go) on Windows.

This means the GOPATH environment variable is not necessarily set to anything in particular.

You can still use os.Getenv to get the value, but in case it is not set you need to make sure that you use the the plattform-specific default value instead, for example using mitchellh/go-homedir:

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")
}

huangapple
  • 本文由 发表于 2015年9月18日 18:29:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/32649770.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定