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

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

How to import platform-specific struct?

问题

我有一个以以下行开头的文件中的结构体:

// +build windows

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

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

如何解决这个困境?

英文:

I've got a struct in a file that begins with this line:

// +build windows

Therefore it will only be built on Windows. However, the part of the application that initializes everything needs to check if it is running on Windows and if so, create an instance of the struct. I have no idea how to do this without breaking things on other platforms.

For example, if the file contains a function newWindowsSpecificThing() and I compile on Linux, the function won't exist because it is defined in a file that isn't being compiled. (And, of course, this will produce an error.)

How do I work around this dilemma?

答案1

得分: 4

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

对于你的问题,我会采取相同的方法,但使用一些执行内部工作的通用方法。在你的应用逻辑中,你会调用那个函数,在你的file_unix.go文件中,你会定义该函数为空(空函数体)。

英文:

I think your solution would be to have some method on your struct which is used on all platforms. Look at how the dir_*.go files work for the os package. The func (file *File) readdirnames(n int) (names []string, err error) is available on all platforms by providing it in dir_plan9.go, dir_unix.go and dir_windows.go.

For your problem, I'd take the same approach but with some generic method that does internal work. In your application logic you'd call that function and in your file_unix.go file you'd define that function to do nothing (empty body).

答案2

得分: 3

在某个地方,你明显有一个调用newWindowsSpecificThing()的函数。这个函数应该在一个特定于Windows的文件中。如果是这样的话,那么它不可用就无关紧要了。你提到了一个“检查是否在Windows上运行”的语句if runtime.GOOS == "windows",这表明在某个地方有这样的判断。与其这样,不如将整个if语句移到一个在特定于Windows的文件中定义的函数中。你还需要在一个!windows的文件中定义该函数,这也是可以的。

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

func Setup() *config {
    var cfg *config
    // 设置cfg的可移植部分
    return PlatformSpecificSetup(cfg)
}

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

type config struct {
  // 独立的部分
  plat *platformConfig
}

然后只需在每个平台文件中定义platformConfig,但实际上我发现这样做更麻烦而不值得。

英文:

Somewhere you clearly have a function that calls newWindowsSpecificThing(). That should be in a Windows-specific file. If it were, then it wouldn't matter that it isn't available. The fact that you have something "check if it is running on Windows" suggests a if runtime.GOOS == "windows" statement somewhere. Rather than have that, move the entire if into a function that is defined in a Windows-specific file. You'll also need to define that function in a !windows file, which is fine.

As an example from my code, I have a function:

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

I then have a file marked // +build windows that defines PlatformSpecificSetup() one way, and another marked // +build !windows that defines it another. I never have to check runtime.GOOS and I never have to deal with undefined data types. The config struct itself is defined in those files, so it can have different fields for each platform (as long as they agree enough for Setup()). If I were being more careful, I could create a struct like:

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

And then just define platformConfig in each platform file, but in practice I've found that more trouble than it's worth.

huangapple
  • 本文由 发表于 2015年10月24日 08:22:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/33313210.html
匿名

发表评论

匿名网友

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

确定