这是我目前使用的方法,我认为它能够完成任务,但一定有更好的方法:
func isWindows() bool {
return os.PathSeparator == '\\' && os.PathListSeparator == ';'
}
你可以看到,在我这种情况下,我只需要知道如何检测Windows,但我想知道如何检测任何平台/操作系统的方法。
Play:
这是我目前使用的方法,我认为它能够完成任务,但一定有更好的方法:
func isWindows() bool {
return os.PathSeparator == '\\' && os.PathListSeparator == ';'
}
你可以看到,在我这种情况下,我只需要知道如何检测Windows,但我想知道如何检测任何平台/操作系统的方法。
Play:
如果您想根据操作系统有不同的实现,最好在具有该功能实现的文件中添加构建标签,并对每个文件进行标记。标准库中的许多地方都使用了这种方法,例如在os
包中。
这些所谓的“构建约束”或“构建标签”在这里进行了解释。
假设您有常量PATH_SEPARATOR
,并希望根据平台而异,则可以创建两个文件,一个用于Windows,另一个用于Unix(除Windows之外的其余平台):
/project/path_windows.go
/project/path_unix.go
这些文件的代码如下:
path_windows.go
// +build windows
package project
const PATH_SEPARATOR = '\\'
path_unix.go
// +build !windows
package project
const PATH_SEPARATOR = '/'
现在您可以在代码中访问PATH_SEPARATOR
,并使其依赖于平台。
如果您想在运行时确定操作系统,请使用runtime.GOOS
变量:
if runtime.GOOS == "windows" {
fmt.Println("Hello from Windows")
}
虽然这被编译到运行时中,因此忽略了环境,
但您仍然可以相对确定该值是正确的。
原因是每个值得区分的平台都需要重新编译,因为不同的可执行文件格式,
因此具有新的GOOS
值。
// +build !windows
,而在 path_windows.go 文件中应该添加 // +build windows
。我已经编辑了上面的答案以显示它们应该放在哪里。它们必须出现在 package
语句之前,并在后面跟随一行空白,以免被解释为包的文档说明。 - Tim Lewisdata_windows.go
中的GetData
函数因为data_unix.go
中的GetData
而被“重新声明”。两者都有适当的构建约束(data_windows.go
有+build windows
,data_unix.go
有+build !windows
),并且在package
语句之前有一个空行,但仍然无法工作。有什么想法吗? - user16442705go build -o ... cli/*.go
,所以它正在构建所有的 Go 文件,而不考虑构建约束。我将其更改为 go build -o ... ./cli
,这样就可以工作了。 - user16442705你看过运行时包吗?它有一个GOOS常量:http://golang.org/pkg/runtime/#pkg-constants
runtime.GOOS
,这个方法可以正常工作,例如:http://play.golang.org/p/0dDIEoFXfx - Nick Craig-Wood现在是2023年,针对go 1.18+的正确答案是:
在运行时,您需要:
if runtime.GOOS == "windows" {
// windows specific code here...
}
os.PathSeparator
例如:
如果你需要获取PATH环境变量使用的路径列表分隔符
- c:\program files
- /usr/local/bin
os.PathListSeparator
例如:
- /usr/local/bin:/usr/local:
- "C:\windows";"c:\windows\system32";
由于这是一个较旧的问题和答案,我找到了另一种解决方案。
您可以简单地使用os包中定义的常量。该常量返回一个rune
,因此您需要进行字符串转换。
string(os.PathSeparator)
string(os.PathListSeparator)
我在Go 1.17.1上进行了测试,确实对我有效。
package main
import (
"fmt"
"runtime"
)
func main(){
fmt.Println(runtime.GOOS)
}
Output:
darwin
我在寻找其他东西时偶然发现了这个,注意到这篇文章的年龄,所以我会添加一个更加更新的补充。如果你只是想处理正确的文件路径,我建议使用filepath.Join()。它可以消除所有操作系统问题的猜测。如果你需要更多的东西,除了文件路径外,使用运行时常量(runtime.GOOS
和runtime.GOARCH
)是最好的方法:playground example
使用 path
:
package main
// Importing fmt and path/filepath
import (
"fmt"
"path/filepath"
)
// Calling main
func main() {
fmt.Println(filepath.Join("/", "/")) // out: /
fmt.Println(filepath.Join(""))// out:
fmt.Println(filepath.Join("dirname", "dirsubname")) // out: dirname/subdirname
fmt.Println(filepath.Join(".")) // out: .
}
或使用 GOOS
:
os := runtime.GOOS
switch os {
case "windows":
fmt.Println("Windows")
case "darwin":
fmt.Println("MAC operating system")
case "linux":
fmt.Println("Linux")
default:
fmt.Printf("%s.\n", os)
}
@nemo 的第一个答案是最合适的,我只想指出,如果您目前是 gopls 语言服务器的用户,则 构建标签 可能无法按预期工作。
目前还没有解决方案或解决方法,您可以做的最多就是更改编辑器的 lsp 配置(vscode、neovim、emacs 等),以选择一个构建标签,以便能够在不出错的情况下编辑带有该标签的文件。 使用其他标签编辑文件将无法正常工作,尝试选择多个标签也会失败。 这是问题 github@go/x/tools/gopls 的当前进展。