在Go中封装特定于平台的代码的正确方法是什么?

时间:2016-02-16 09:46:09

标签: go architecture cross-platform

我想开发一个小型Go应用程序,它向演示者的观众显示使用过的关键笔划快捷方式。

要挂钩键盘事件,我将不得不使用一些特定于平台的代码。 封装平台特定代码的Go方式是什么?我一直在搜索编译器开关或平台模块等关键字,但我无法真正找到相关内容。

2 个答案:

答案 0 :(得分:3)

平台特定代码的解决方案是build constraints

  

构建约束(也称为构建标记)是以

开头的行注释
subscribeNext
     

列出了文件应包含在包中的条件。约束可能出现在任何类型的源文件中(不仅仅是Go),但它们必须出现在文件顶部附近,前面只有空行和其他行注释。这些规则意味着在Go文件中,构建约束必须出现在package子句之前。

因此,基本上每个特定于平台的Go代码都应该进入不同的文件,并且您可以使用它们所针对的目标标记每个Go文件。

例如,如果文件包含Linux特定代码(例如系统调用),请使用以下命令启动它:

// +build

如果文件包含Windows特定的系统调用,请以:

启动它
// +build linux

更多"选项"可用,阅读链接的文档。例如,您可以为OS,Architecture,Go版本,正在使用的编译器指定约束。您还可以指定将使用逻辑OR或AND解释的多个约束,或者您可以使用否定(例如,此代码适用于除linux之外的每个目标平台)。

您甚至可以使用以下约束标记要忽略的// +build windows 文件:

.go

请注意,构建约束是特定于编译器的。如果特定编译器无法识别构建约束,则编译器将忽略该文件。作为一个例子,Go AppEngine SDK附带了一个内置的,经过修改的Go编译器,它还能识别

// +build ignore

约束,这意味着源文件仅适用于Google App Engine平台。 "定期" Go编译器将忽略该文件,如果有人试图在没有Go AppEngine SDK的情况下构建代码,则可能不会出现一堆编译器错误。

答案 1 :(得分:1)

虽然@icza's answer绝对是OP关于条件编译问题的正确权威答案,但在这个特定情况下,更简单的方法可能是值得的。

Go是一种语言,旨在在每个平台上编译相同的(使用相同的编译器),以鼓励跨平台代码和库重用。 Go不是C / C ++,必须花费时间明确地编写跨平台代码。

当然,平台不可知性只能达到Go的运行时,并且您正在尝试捕获按键,因为没有真正的单一平台无关的解决方案。

因此,我对此用例的简单建议 类似于以下内容:

package main

import (
    "runtime"
    kp "kplib"
)

func main () {
    switch runtime.GOOS {
    case "windows":
        kp.WinKey()
    case "darwin":
        kp.MacKey()
    case "linux":
        kp.UnixKey()
    default:
        kp.TryKey()
    }
}

通过隐式保证,假设kplib将在任何地方编译(只需确保在给定平台上调用正确的方法!)。