可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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:
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:
You should use go/build package.
package main import ( "fmt" "go/build" ) func main() { fmt.Println(build.Default.GOPATH) }
回答3:
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") }
回答4:
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.