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

问题描述 投票:0回答:3

我想开发一个小型 Go 应用程序,向演示文稿的观众显示所使用的按键快捷键。

要挂钩键盘事件,我必须使用一些特定于平台的代码。 封装特定于平台的代码的 Go 方式是什么?我一直在搜索诸如编译器开关或平台模块之类的关键字,但我找不到相关内容。

go architecture cross-platform
3个回答
28
投票

平台特定代码的解决方案是构建约束

注意: 在 Go 1.17 之前,语法是以

// +build
开头的注释行,但 Go 1.17 引入了
//go:build
编译指示,这是现在的首选方式。

构建约束,也称为构建标签,是开始的行注释

//go:build

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

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

例如,如果文件包含 Linux 特定代码(例如系统调用),则以以下方式启动:

//go:build linux

如果文件包含 Windows 特定的系统调用,请使用以下命令启动它:

//go:build windows

还有更多“选项”可用,请阅读链接的文档。例如,您可以指定对操作系统、架构、Go 版本、所使用的编译器的约束。您还可以指定多个约束,这些约束将用逻辑 OR 或 AND 进行解释,或者您可以使用否定(例如,此代码适用于除 Linux 之外的每个目标平台)。

您甚至可以使用以下约束标记要忽略的

.go
文件:

//go:build ignore

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

//go:build appengine

约束,这意味着源文件仅适用于 Google App Engine 平台。 “常规”Go 编译器将忽略该文件,这样,如果有人尝试在不使用 Go AppEngine SDK 的情况下构建代码,您就有可能不会出现一堆编译器错误。


9
投票

虽然@icza的答案绝对是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

将在任何地方编译(只要确保在给定平台上调用正确的方法!)。


1
投票
要使代码特定于平台,您可以选择

build constraints

了解更多信息

Windows

//go:build windows // +build windows

不是Windows

//go:build !windows // +build !windows

不是 Windows 和 Darwin

//go:build !windows && !darwin // +build !windows,!darwin

Mac

//go:build darwin // +build darwin

Linux

//go:build linux // +build linux

示例

//go:build windows // +build windows package main func main() { // windows specific code }
或者您可以使用 

file naming convention

 将代码放在不同操作系统的单独文件中。

例如:-

路径

    路径.go
  • path_windows.go
  • path_darwin.go
  • path_linux.go

为不同的操作系统和架构构建Go应用程序

© www.soinside.com 2019 - 2024. All rights reserved.