如何导入特定于平台的结构?

How to import platform-specific struct?

我在文件中有一个以此行开头的结构:

// +build windows

因此它只会建立在 Windows 上。但是,初始化所有内容的应用程序部分需要检查它是否是 Windows 上的 运行,如果是,则创建该结构的实例。我不知道如何在不破坏其他平台的情况下做到这一点。

例如,如果文件包含一个函数 newWindowsSpecificThing() 而我在 Linux 上编译,该函数将不存在,因为它是在一个未被编译的文件中定义的。 (当然,这会产生错误。)

我该如何解决这个难题?

我认为您的解决方案是在您的结构上使用一些可在所有平台上使用的方法。查看 dir_*.go 文件如何为 os 包工作。 func (file *File) readdirnames(n int) (names []string, err error) 通过在 dir_plan9.godir_unix.godir_windows.go.

中提供,可在所有平台上使用

对于您的问题,我会采用相同的方法,但会使用一些 internal 起作用的通用方法。在您的应用程序逻辑中,您将调用该函数,并在您的 file_unix.go 文件中将该函数定义为不执行任何操作(空主体)。

某处您显然有一个调用 newWindowsSpecificThing() 的函数。那应该在 Windows 特定的文件中。如果是,那么它不可用也没关系。你有一些东西 "check if it is running on Windows" 的事实表明某处有一个 if runtime.GOOS == "windows" 语句。与其拥有它,不如将整个 if 移动到一个在 Windows 特定文件中定义的函数中。您还需要在 !windows 文件中定义该函数,这很好。

以我的代码为例,我有一个函数:

func Setup() *config {
    var cfg *config
    // setup portable parts of cfg
    return PlatformSpecificSetup(cfg)
}

然后我有一个标记为 // +build windows 的文件定义了 PlatformSpecificSetup() 一种方式,另一个标记为 // +build !windows 的文件定义了另一种方式。我永远不必检查 runtime.GOOS,也永远不必处理未定义的数据类型。 config 结构本身在这些文件中定义,因此每个平台可以有不同的字段(只要它们对 Setup() 足够同意)。如果我更小心一些,我可以创建一个结构,如:

type config struct {
  // independent stuff
  plat *platformConfig
}

然后只需在每个平台文件中定义 platformConfig,但在实践中我发现麻烦得不偿失。