如何在Go中可靠地检测OS /平台


77

这是我当前正在使用的,我认为可以完成工作,但是必须有一种更好的方法:

func isWindows() bool {
    return os.PathSeparator == '\\' && os.PathListSeparator == ';'
}

如您所见,在我的情况下,我只需要知道如何检测窗口即可,但是我想知道检测任何平台/操作系统的方法。

玩:

http://play.golang.org/p/r4lYWDJDxL


2
使用Posix分隔符“ /”,当前版本的Windows可以正常运行。蝙蝠脚本和Windows的非Posix旧版本只需要反斜杠。
Rick-777

您可以定义“当前”吗?在过去的几周里,我已经被硬编码'/'烧死了
mdwhatcott

2
Windows 95、98 ME和所有早期版本都需要反斜杠。Windows 2000,NT和更高版本将反斜杠和正斜杠等效。反斜杠提供与较早版本的兼容性,而正斜杠提供与Posix的兼容性。
Rick-777

感谢您的澄清@ Rick-777。
mdwhatcott

Answers:


145

编译时检测

如果要执行此操作以根据操作系统使用不同的实现,则具有实现该功能的单独文件并向每个文件添加构建标记会更有用。这在标准库的许多地方都使用过,例如ospackage中

这些所谓的“构建约束”或“构建标签”在此处进行了说明。

假设您有常量,PATH_SEPARATOR并且希望该平台依赖,您将制作两个文件,一个用于Windows,另一个用于(unix)其余部分:

/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价值。


我试图运行此程序,但出现了一些奇怪的错误。path_windows.go:4:24:在此块中重新声明了PATH_SEPARATOR。在path_unix.go:4:24上的先前声明我只是不明白...编译器不明白吗?
拉蒙·贾·史密斯

2
@ RamonJ.A.Smit您将需要向这些文件添加构建约束,例如:path_unix.go应该具有// +build !windows,path_windows.go应该具有// +build windows。我编辑了上面的答案,以显示它们应该去的地方。它们必须在package语句之前,并且后跟空白行,因此它们不会被解释为软件包的文档。
蒂姆·刘易斯

感谢您的额外投入!会玩这个。谢谢:-)
拉蒙·贾·史密斯


0

我只是偶然发现了这个东西,然后注意到了这篇文章的年代,所以我将添加更多更新的内容。如果您只是想处理正确的文件路径,则可以使用filepath.Join()。它消除了操作系统问题中的所有猜测。如果除了文件路径之外,还需要更多的东西,那么可以使用运行时常量(runtime.GOOSruntime.GOARCH):Playground示例


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.