Go语言能够经过go/build包里定义的tags和命名约定来让Go的包能够运行不一样的代码。html

标签编译

在源代码里添加标注,一般称之为编译标签(build tag)。编译标签采用靠近源代码文件顶部用注释的方式添加。go build在构建一个包的时候会读取这个包里的每一个源文件而且分析编译便签,这些标签决定了这个源文件是否参与本次编译。linux

编译标签由空格分隔的编译选项(options)以”或”的逻辑关系组成(a build tag is evaluated as the OR of space-separated options)。

每一个编译选项由逗号分隔的条件项以逻辑”与”的关系组成( each option evaluates as the AND of its comma-separated terms)

每一个条件项的名字用字母+数字表示,在前面加!表示否认的意思(each term is an alphanumeric word or, preceded by !, its negation)

注:一个源文件能够有多个编译标签,多个编译标签之间是逻辑“与”的关系,一个编译标签能够包括由空格分割的多个标签,这些标签是逻辑“或”的关系。例子:git

// +build linux darwin

// +build 386

这个将限制此源文件只能在 linux/386或者darwin/386平台下编译

下边以json包的适配为例,介绍标签编译:github

背景

Golang提供的标准json解析库——encoding/json,在开发高性能、高并发的网络服务时会产生性能问题。替代的方案是使用高性能的json解析库,好比json-iterator和easyjson。在正式引用高性能的json解析库(以json-iterator为例)一般的作法是小范围的进行测试,此时就会出现两个库并存的时候,解决方案是使用标签编译选择运行的解析库web

统一的JSON库

如今咱们须要两个库并存,因此咱们先得统一这两个库的用法(参考适配器模式),这里咱们使用一个自定义的json包来适配encoding/json和json-iteratorjson

json/json.go网络

// +build !jsoniter

//必须留一行空格,不然会报重定义的错误

package json

import (

"encoding/json"

"fmt"

)

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {

fmt.Println("Use [encoding/json] package")

return json.MarshalIndent(v,prefix,indent)

}

json/jsoniter.go并发

// +build jsoniter

package json

import (

"fmt"

"github.com/json-iterator/go"

)

var (

json = jsoniter.ConfigCompatibleWithStandardLibrary

)

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {

fmt.Println("Use [jsoniter] package")

return json.MarshalIndent(v,prefix,indent)

}

目录结构以下:svg

json

├── json.go

└── jsoniter.go

注: 上述例子中若是编译标签 和包的声明 之间没有空行隔开,编译标签会被当作包声明的注释而不是编译标签,切记空行必需要有。函数

main函数

此处引用的json包下的两个go文件中都有MarshalIndent函数定义,而且签名一致,但它们又是使用不一样的json解析库实现,此处至关于作了统一的适配包装,因此调用能够统一。

package main

import (

"fmt"

"pracitice/json_test/json"

)

type user struct {

Name string

Age int

}

func main() {

u := user{"xiyan",7}

b, err := json.MarshalIndent(u, "", "")

if err != nil {

fmt.Println(err)

} else {

fmt.Println(string(b))

}

}

直接运行go run main.go结果:

Use [encoding/json] package

{

"Name": "xiyan",

"Age": 7

}

使用标签编译运行go run -tags=jsoniter main.go

Use [jsoniter] package

{"Name":"xiyan","Age":7}

总结

标签编译的关键在于 -tags=jsoniter , -tags 这个标志,是Go语言为咱们提供的条件编译方式之一。若是咱们不是运行,而是编译构建的话,改成go build -tags=jsoniter 便可生成调用了对应包的可执行文件。

// +build !jsoniter

表示,tags不是jsoniter的时候编译这个Go文件。

// +build jsoniter

表示,tags是jsoniter的时候编译这个Go文件。

这两行是Go语言条件编译的关键。+build能够理解标签编译tags的声明关键字,后面跟着tags的条件。

文件后缀

使用这种方案比编译标签要简单,go/build能够在不读取源文件的状况下就能够决定哪些文件不须要参加编译。文件命名约定能够在go/build包里找到详细的说明,简单来讲若是你的源文件包含后缀:_$GOOS.go,那么这个源文件只会在这个平台下编译, _$GOARCH.go也是如此。 这两个后缀能够结合在一块儿使用,顺序只能为:_$GOOS_$GOARCH.go

例子以下:

mypkg_freebsd_arm.go // only builds on freebsd/arm systems

mypkg_plan9.go // only builds on plan9

源文件不能只提供条件编译后缀,还必须有文件名,_linux.go、_freebsd_386.go 这两个源文件在全部的平台下都会被忽略掉,由于go/build将会忽略全部如下划线或者点开头的源文件 。

参考资料

golang不编译.html,golang之条件编译相关推荐

  1. golang不编译.html,Golang 编译 条件编译

    条件编译: 标签编译:( build tag ) // +build { GOOS }, { GOOS }, { !GOOS } // +build (linux AND 386) OR (darwi ...

  2. golang不编译.html,Golang编译-ldflags -X 在vendor中不生效的问题

    Golang项目在编译链接的时候可以通过 -ldflags -X 来给代码中的变量赋值,然而这天我却遇到了一个诡异的问题-- 版本信息 很多应用在 release 时都会给自己打上版本信息,方便使用者 ...

  3. golang语言编译的二进制可执行文件为什么比 C 语言大(转载)

    最近一位朋友问我"为什么同样的hello world 入门程序"为什么golang编译出来的二进制文件,比 C 大,而且大很多.我做了个测试,来分析这个问题.C 语言的hello ...

  4. golang python rpc_grpc - 使用 golang 带你从头撸一套 RPC 服务(一)

    gRPC 是一个高性能.开源和通用的 RPC 框架,面向移动和 HTTP/2 设计,带来诸如双向流.流控.头部压缩.单 TCP 连接上的多复用请求等特.这些特性使得其在移动设备上表现更好,更省电和节省 ...

  5. Golang入门教程(二)Ubuntu16.04下安装golang(实例:Golang 定时任务管理器)

    通过两种方式安装 一.通过apt-get安装 1.安装 sudo apt-get install golang 2.设置GOPATH变量 GOPATH是扩展库的目录,Go先搜索标准库目录,然后搜索GO ...

  6. Golang指南:顶级Golang框架、IDE和工具列表

    Golang指南:顶级Golang框架.IDE和工具列表 https://www.itcodemonkey.com/article/1053.html 2017-10-30 17:21:58 分类:人 ...

  7. 超详细的golang学习指南,golang知识图谱

    golang知识图谱 基础知识 go 语言关键字.标识符.数据类型.变量.流程控制.函数.数组.闭包 关键字 break - 使用break关键字可以终止循环并继续执行其余代码 case - 这是sw ...

  8. Golang(1)Golang语言简介

    Golang(1)Golang语言简介 Golang(2)win10下安装Go语言 Golang(3)CentOS7系统安装Go语言 一.Golang的学习方向 (1)区块链研发工程师 (2)Go服务 ...

  9. 【Golang第6章:排序和查找】golang怎么排序,golang的顺序查找和二分查找,go语言中顺序查找二分查找介绍和案例

    介绍 这个是在B站上看边看视频边做的笔记,这一章是GO语言的排序和查找 有golang怎么排序,golang的顺序查找和二分查找,go语言中顺序查找二分查找介绍和案例,具体请看[文章目录] 配套视频自 ...

最新文章

  1. C++返回栈上的数组(局部变量)问题探索
  2. 震撼来袭 | 人工智能Paper精读班,视频讲解+代码实现(还剩28个名额)
  3. Objective-C优缺点
  4. 信息学奥赛一本通(1148:连续出现的字符)
  5. 基于JAVA+SpringMVC+Mybatis+MYSQL的企业客户管理系统
  6. 3项目估算表_浮动油封生产项目可行性研究报告
  7. 【OCP题库-12c】最新CUUG OCP 071考试题库(72题)
  8. 阿里云搭建 ftp 服务器
  9. 计算机技术产生的就业辩论,计算机与软件技术系辩论赛决赛
  10. python中reduce是什么意思_python-reduce函数
  11. Cython使用问题集合
  12. 制造业数字化转型内涵和过程
  13. 元宇宙产业委通过央链直播召开第十次新闻通报会:第十一批入会成员名单公布
  14. 你遇到过启动电脑以后系统桌面无法显示吗
  15. Android的识花软件推荐,形色、苗叔、花伴侣三大主流识花软件全面评测
  16. 用HTML里面的表格制作可以下拉的导航栏,excel表格中下拉菜单制作有什么方法
  17. Node.js的用户交互(使用readline模块)
  18. JavaWeb之JSP和MVC三层架构
  19. Citrix XenDesktop
  20. 2018年BAT薪资

热门文章

  1. 使用最小堆使用优先级队列(c语言版本)
  2. 在Ubuntu 14.04 64bit上搭建单机本地节点Spark 1.3.0环境
  3. Mastering Algorithms with C中文版附带源码说明
  4. 解决 sh: java: command not found 问题
  5. 到这个年纪为什么我还要开始学习理解参与区块链?
  6. [转帖]tar高级教程:增量备份、定时备份、网络备份
  7. Appium+Python 自动化测试一之:环境安装(Android篇)
  8. P1979 [NOIP]华容道
  9. Spark Shuffle原理解析
  10. Linux课堂随笔---第四天