Go语言有一个不(奇)错(葩)的设计,就是build constraints(构建约束)。可以在源码中通过注释的方式指定编译选项,比如只允许在linux下,或者在386的平台上编译啊之类的;还可以通过文件名来约束构造,比如xxxx_linux.go,就是只允许在linux下编译,xxx_windows_amd64.go就是只允许在windows x64下编译。

构建约束可以在很多文件中使用,不单单是GO文件。但是必须要注意的是,通过注释实施构建约束的话,比如要放在文件的开头,要优先于空行或和其他注释之前。也就是说必须在package语句的前面写。这就有个很蛋疼的文件,因为GO的godoc是可以提取代码中的注释然后转换为文档的。在package语句之前写的注释会被认为是包级别的注释。而构建约束又在所有注释之前,那么为了区分包级别的注释,就要在构建约束与包级别的注释之间添加空行进行区分。(这个设计看上去不得不承认很囧)。

通过注释实施的构建约束还可以进行逻辑表达。就是and, or之类的语义。GO的官方是这么定义的:如果构建约束中有空格,那么就是OR关系,如果是逗号分隔,那么就是AND关系。!表示not。比如

// +build linux,386 darwin,!cgo

就是表示(linux AND 386) OR (darwin AND (NOT cgo))

而且GO还支持多行的构建约束,多行之间是AND关系,比如

// +build linux darwin

// +build 386

就是表示(linux OR darwin) AND 386

GO官方还定义了常用的一些约束

  • 限制目标操作系统,也就是要和runtime.GOOS一致
  • 限制目标架构平台,也就是要和runtime.GOARCH一致
  • GC或者GCCGO等编译器支持的约束
  • cgo约束,也就是说如果支持cgo的话,就可以参与编译
  • go1.1,表示从go1.1开始向前兼容
  • go1.2,表示从1.2开始向前兼容
  • go.13,表示从1.3开始向前兼容
  • 自定义的约束

如果你想临时让某个文件不参与编译,可以添加注释约束下: // +build ignore

通过注释来实现构建约束有点蛋疼,而且GO官方定义里还表示可以自定义约束,那么可以用来干嘛?学GO的人都知道GO内建了单元测试的框架,跑跑一般的单元测试还是非常嗨皮的,但是如果要做一些简单的集成测试就令人拙计了,因为go test默认就是跑最基本的单元测试。那么怎么只执行集成测试的代码呢?其实就可以通过构建约束来实施。比如我们在集成测试的GO文件中加上 // +build integration 然后运行命令 go test –tags=”integration”就可以只运行我们的集成测试代码了。

虽然通过注释的方式对构建进行了约束,但是文件名的构建约束反而让人觉着很不错呢,至少在工程里看着一目了然。文件名前缀只要含有_GOOS, _GOARCH, _GOOS_GOARCH的就可以了。比如xxx_linux.go yyy_windows_amd64.go , zzzz_386.s等等。

Go build constraints的更多相关文章

  1. 说说Golang的使用心得

    13年上半年接触了Golang,对Golang十分喜爱.现在是2015年,离春节还有几天,从开始学习到现在的一年半时间里,前前后后也用Golang写了些代码,其中包括业余时间的,也有产品项目中的.一直 ...

  2. Go命令官方指南【原译】

    启动错误报告 编译包和依赖项 删除目标文件和缓存的文件 显示包或符号的文档 打印Go环境信息 更新包以使用新API Gofmt(重新格式化)包源 通过处理源生成Go文件 下载并安装包和依赖项 编译并安 ...

  3. Golang之go 命令用法

    Go 命令 Go 命令 Go语言自带有一套完整的命令操作工具,你可以通过在命令行中执行go来查看它们: 图1.3 Go命令显示详细的信息 这些命令对于我们平时编写的代码非常有用,接下来就让我们了解一些 ...

  4. 浏览器与go语言的websocket通信

    简介WebSocket是HTML5一种新的协议.顾名思义,它在服务器和浏览器之间建立了全双工通信. 需求背景区块链测试系统web前端平台需要动态接收后端发送的状态信息改变一次测试session过程的状 ...

  5. 04 Go 1.4 Release Notes

    Go 1.4 Release Notes Introduction to Go 1.4 Changes to the language For-range loops Method calls on ...

  6. 01 Go 1.1 Release Notes

    Go 1.1 Release Notes Introduction to Go 1.1 Changes to the language Integer division by zero Surroga ...

  7. Go按照条件编译

    Go 支持按照条件编译,具体来说它是通过 go/build包 里定义的tags和命名约定来让Go的包可以管理不同平台的代码 . 我们这里以下面这个开源项目为例,来看Go的按条件编译, 这个开源项目是把 ...

  8. go学习笔记-常见命令

    常见命令 go 命令 可以在控制台执行go来查看 go Go is a tool for managing Go source code. Usage: go <command> [arg ...

  9. Golang的标准命令简述

    Golang的标准命令简述 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Go本身包含了大量用于处理Go程序的命令和工具.go命令就是其中最常见的一个,它有许多子命令,接下来就跟随 ...

随机推荐

  1. 火焰图分析openresty性能瓶颈

    注:本文操作基于CentOS 系统 准备工作 用wget从https://sourceware.org/systemtap/ftp/releases/下载最新版的systemtap.tar.gz压缩包 ...

  2. MVC常遇见的几个场景代码分享

    本次主要分享几个场景的处理代码,有更好处理方式多多交流,相互促进进步:代码由来主要是这几天使用前端Ace框架做后台管理系统,这Ace是H5框架里面的控件效果挺多的,做兼容也很好,有点遗憾是控件效果基本 ...

  3. 零OCR基础6行代码实现C#验证码识别

    这两天因为工作需要,要到某个网站采集信息,一是要模拟登陆,二是要破解验证码,本想用第三方付费打码,但是想想网上免费的代码也挺多的,于是乎准备从网上撸点代码下来,谁知道,撸了好多个都不行,本人以前也没接 ...

  4. JS继承类相关试题

    题目一: //有关于原型继承的代码如下:function Person(name) {   this.name = name;}Person.prototype = {     getName : f ...

  5. C++随笔:.NET CoreCLR之GC探索(2)

    首先谢谢 @dudu 和 @张善友 这2位大神能订阅我,本来在写这个系列以前,我一直对写一些核心而且底层的知识持怀疑态度,我为什么持怀疑态度呢?因为一般写高层语言的人99%都不会碰底层,其实说句实话, ...

  6. 在MySQL数据库中创建一个完整的表

    1.登陆成功后,首先进入某一个数据库 (不是指数据库服务器) use t1; //t1是数据库名 如图所示: 2.在此数据库中建立数据库表 2.1 先建立表结构(可以理解为表的列名,也就是字段名)在实 ...

  7. MongoDB学习笔记三—增删改文档上

    插入insert 单条插入 > db.foo.insert({"bar":"baz"}) WriteResult({ }) 批量插入 > db.fo ...

  8. Create a bridge using a tagged vlan (8021.q) interface

    SOLUTION VERIFIED April 27 2013 KB26727 Environment Red Hat Enterprise Linux 5 Red Hat Enterprise Li ...

  9. osi(open system interconnection)模型的通俗理解

    OSI模型的理解: 以你和你女朋友以书信的方式进行通信为例. 1.物理层:运输工具,比如火车.汽车. 2.数据链路层:相当于货物核对单,表明里面有些什么东西,接受的时候确认一下是否正确(CRC检验). ...

  10. 免费开源的 .NET 分布式组件库 Exceptionless Foundatio

    前言 在互联网时代,分布式应用.系统变得越来越多,我们在使用 .Net 技术构建分布式系统的时候,需要使用到一些组件或者是助手库来帮助我们提高生产力以及应用程序解耦,但是纵观.Net圈,能够符合要求的 ...