学习golang的条件编译

昨天学习了go generate,今天学习另外一个知识点,一样是跟注释有关的知识点。golang的条件编译,也叫编译约束(build constraints)。

应用场景

条件编译可以在适应不同平台操作系统的代码上体现。不同的操作系统平台,对某些特性的支持不太一样,但是往往在业务层面上的代码不会去关注,所以需要对底层的代码进行一些封装。比如,Windows和Linux的home目录是不一样的,而我们的业务需要读取home目录,那此时我们就可以用条件编译来达到效果。

条件编译的两种形式

条件编译可以通过两种方式实现:

  • 在源文件开头添加注释;
  • 以文件名后缀的方式实现。

以添加注释的方式

注释的格式如下:

// +build tags

tags可以是操作系统,也可以是编译器选项,具体有什么可以填的,请往后面看,我们先看个例子来有个大概的印象:

// +build windows

package main

import "fmt"

func echo()  {
    fmt.Print("windows")
}
// +build linux

package main

import "fmt"

func echo()  {
    fmt.Print("linux")
}
package main

func main()  {
    echo()
}

我写了两个文件,都有echo方法,并在main函数中调用了echo方法,现在运行的话,在Windows环境下会打印“windows”,在Linux环境下会打印“linux”。看到这应该就能大致懂了什么是条件编译以及它的应用场景。

那么我们当我们有多个编译条件呢?比如,Linux下的amd64环境,那应该怎么定义tags?在源文件开头的注释中,可以有多个build的定义,比如:

// +build linux
// +build amd64

也可以这么写

// +build linux,amd64

用逗号分隔表示的是“与”的逻辑,用空格分隔表示“或”的逻辑,看下面的例子:

// +build linux,cgo darwin,cgo

这表示在Linux或苹果的环境下,用cgo编译。
还有一点挺重要的要注意就是在注释之后一定要空一行。如果是想表示只要不在Windows环境下都可以编译,应该这么写:

// +build !windows

如果+build后面的tags是没有定义的,那么编译时会忽略,比如:

// +build abc

现在我们看看有那些tags是我们能填的,从官方文档可以看到以下选项:

- the target operating system, as spelled by runtime.GOOS
- the target architecture, as spelled by runtime.GOARCH
- the compiler being used, either "gc" or "gccgo"
- "cgo", if ctxt.CgoEnabled is true
- "go1.1", from Go version 1.1 onward
- "go1.2", from Go version 1.2 onward
- "go1.3", from Go version 1.3 onward
- "go1.4", from Go version 1.4 onward
- "go1.5", from Go version 1.5 onward
- "go1.6", from Go version 1.6 onward
- "go1.7", from Go version 1.7 onward
- "go1.8", from Go version 1.8 onward
- "go1.9", from Go version 1.9 onward
- "go1.10", from Go version 1.10 onward
- "go1.11", from Go version 1.11 onward
- "go1.12", from Go version 1.12 onward
- "go1.13", from Go version 1.13 onward
- "go1.14", from Go version 1.14 onward
- any additional words listed in ctxt.BuildTags

以文件命名后缀的方式

文件命名的方式比较简单,可以以下面几种形式的命名来条件编译:

*_GOOS //如:file_linux.go,表示只在Linux下编译
*_GOARCH //如:file_amd64.go,表示只在amd64下编译
*_GOOS_GOARCH //如:file_linux_amd64.go,表示只在Linux且amd64下编译


欢迎关注我的公众号:onepunchgo,给我留言。

原文地址:https://blog.51cto.com/14664952/2482832

时间: 2024-10-11 09:23:18

学习golang的条件编译的相关文章

学习Golang语言(6):类型--切片

学习Golang语言(1): Hello World 学习Golang语言(2): 变量 学习Golang语言(3):类型--布尔型和数值类型 学习Golang语言(4):类型--字符串 学习Golang语言(5):类型--数组 学习Golang语言(6):类型--切片 在很多应用场景中,数组不能够满足我们的需求.在初始定义数组时,我们并不知道数组所需的长度.因此,我们需要一个大小可以动态变化的数组(动态数组) 在Go语言中,这种"动态数组"成为slice(切片). 但是实际上slic

【One by one系列】一步步学习Golang web框架Gin

一步步学习Golang web框架Gin 建立项目 go mod 管理依赖 cd $gopath\src\github.com\carfield go mod init 就可以看到在src\github.com\carfield 生成了go.mod文件 module github.com/carfield go 1.13 下载gin包 go get -u github.com/gin-gonic/gin ps:由于众所周知的原因,大概率是下不动,所以请修改代理 修改代理 go env -w GO

[dev][go] 学习Golang都需要掌握什么

一 什么? 首先要了解Golang是什么. Golang是一门计算机编程语言:可以编译成机器码的像python一样支持各种特性的高级语言. 由Google发明,发明人之一是K,就是C语言的那个K&R的K. 网站:https://golang.org/ 二 安装环境 安装环境,无外乎就是安装编译器. 有两套(我知道的),一个官方的Go,一个Gcc-Go 这里不讨论GccGo. 2.1 安装 安装官方Go,有两个办法,一个是去网站下载,然后自己解压.另一个是用包管理工具yum,pacman等. 下载

学习golang的历程——持续更新

学习一门语言首先hello world 1,首先建立一个目录,新建一个hello.go的文件 package main import ( "fmt" ) func main() { fmt.Println("hello world") } 2,go run hello.go [email protected] study % go run hello.go hello world 上面我们就完成了我们的基础使命.下面我们正式开始入门 在正式进入写代码之前,推荐大家使

深入学习golang(2)—channel

Channel 1. 概述 “网络,并发”是Go语言的两大feature.Go语言号称“互联网的C语言”,与使用传统的C语言相比,写一个Server所使用的代码更少,也更简单.写一个Server除了网络,另外就是并发,相对python等其它语言,Go对并发支持使得它有更好的性能. Goroutine和channel是Go在“并发”方面两个核心feature. Channel是goroutine之间进行通信的一种方式,它与Unix中的管道类似. Channel声明: ChannelType = (

学习Golang的步骤建议

一.快速入门 通过快速入门可以宏观的了解Go相关知识.快速入门可以去学习 go-tour 国内可以访问的中文版的 go-tour 地址有下面一些: http://gotour.qizhanming.com/#1   也可以自行搭建 go-tour 的环境, 搭建方法参考: http://www.cnblogs.com/ghj1976/archive/2013/03/08/2949237.html https://github.com/meilihao/tour_book/blob/master/

深入学习golang(3)—类型方法

类型方法 在Go语言中,我们可以给任何类型(包括内置类型,但不包括指针和接口)定义方法.例如,在实际编程中,我们经常使用[ ]byte的切片,我们可以定义一个新的类型: type ByteSlice []byte 然后我们就可以定义方法了.例如,假如我们不想使用内建的append函数,我们可以实现一个自己的append方法: func Append(slice, data[]byte) []byte { l := len(slice) if l + len(data) > cap(slice)

深入学习golang(4)—new与make

Go语言中的内建函数new和make是两个用于内存分配的原语(allocation primitives).对于初学者,这两者的区别也挺容易让人迷糊的.简单的说,new只分配内存,make用于slice,map,和channel的初始化. 1. new 这是一个用来分配内存的内建函数,但是与C++不一样的是,它并不初始化内存,只是将其置零.也就是说,new(T)会为T类型的新项目,分配被置零的存储,并且返回它的地址,一个类型为*T的值.在Go的术语中,其返回一个指向新分配的类型为T的指针,这个指

【golang学习】环境搭建

近期项目的需要开始了学习golang的旅程,在此将学习的过程做以记录,方便查看,也希望帮助到大家. 由于我使用的是64位linux环境(redhat 5.2),所以这里就介绍64位的安装方式,其他类似: 1. 下载安装包 自从2014年5月谷歌在国内被封杀之后,我们下载go安装包也得翻墙了,但是为了方便我上传了一个64位linux的包在(地址),你可以直接下载使用. 2.安装 下载完上传到你的linux系统中,比如/opt/go1.1.1.linux-amd64.tar.gz,这是就开始安装了,