golang编译tag学习

news2024/11/26 22:48:58

官方资料

官方解释: https://pkg.go.dev/cmd/go#hdr-Build_constraints ,go help buildconstraint 也能看到描述

根据官方描述,go1.16开始建议使用go:build方式,与+build相比更容易被人阅读。

有关go:build注释的解析: src/go/build/build.go#shouldBuild

有关tag匹配规则: src/go/build/build.go#matchTag

下面是代码片段

func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool {
	if allTags != nil {
		allTags[name] = true
	}

	// special tags
	if ctxt.CgoEnabled && name == "cgo" {
		return true
	}
	if name == ctxt.GOOS || name == ctxt.GOARCH || name == ctxt.Compiler {
		return true
	}
	if ctxt.GOOS == "android" && name == "linux" {
		return true
	}
	if ctxt.GOOS == "illumos" && name == "solaris" {
		return true
	}
	if ctxt.GOOS == "ios" && name == "darwin" {
		return true
	}
	if name == "unix" && unixOS[ctxt.GOOS] {
		return true
	}
	if name == "boringcrypto" {
		name = "goexperiment.boringcrypto" // boringcrypto is an old name for goexperiment.boringcrypto
	}

	// other tags
	for _, tag := range ctxt.BuildTags {
		if tag == name {
			return true
		}
	}
	for _, tag := range ctxt.ToolTags {
		if tag == name {
			return true
		}
	}
	for _, tag := range ctxt.ReleaseTags {
		if tag == name {
			return true
		}
	}

	return false
}

在源文件go/build/syslist.go中可以找到knownOS表示tag中可以填写的OS,以及填写unix标签时匹配的OSunixOS,还有可填写的架构knownArch

BuildTags

BuildTags是编译命令时-tags的参数列表,根据go help build描述-tags为逗号分隔字符串,兼容旧版空格分隔字符串,具体代码: src/cmd/go/internal/work/build.go#tagsFlag

因此go build -tags "a,b,c"这种是新版推荐写法,go build -tags "a b c"这种是旧版兼容写法

ToolTags

ToolTags是初始化时的工具标签,源码位置 src/cmd/go/internal/work/init.go#ToolTags

在源码中我看到ToolTags可以是race,msan,asan,分别对应go build -race,go build -msan``go build -asan,这三种编译参数。最常见的就是race用来检查程序是否存在竞态

ReleaseTags

ReleaseTags是go发布版本标签,源码: src/go/build/build.go#ReleaseTags

根据相关注释发现ReleaseTags最后一个值被认为是当前在用版本。根据这个标签的源码我们发现当使用//go:build go1.18的xxx.go文件时,使用大于等于go1.18版本的go取编译都会匹配成功,也就是说使用go1.19去编译//go:build go1.18的文件也是会成功的。

编译优化

  • 很多人都知道C语言可以在代码里面加上条件编译,认为Go只能基于文件进行条件编译,毕竟一个//go:build xxx将影响一个文件是否能被编译,以及文件命名格式也是影响整个文件是否被编译。
  • 如何做到在某个代码块里面嵌入条件编译呢?实际上Go源码已经有相关方案,可以参考 src/internal/race

race.go内容如下

//go:build race
// +build race

package race

const Enabled = true

norace.go内容如下

//go:build !race
// +build !race

package race

const Enabled = false

然后就会在源码中找到大量 if race.Enabled { ,这种代码,大家都知道执行go build -racerace.Enabled = true那么这部分判断就会执行,否则就不会执行。

我的问题是如果每次运行时都进行这些if判断虽然损耗不了多少性能但却非常不优雅。但实际上Go会在编译时检查确定的判断,当判断为false时这部分代码都会被优化掉,不会编译到可执行程序中。

验证编译优化

package main

const enable = false

func main() {
	if enable {
		println("hello word")
	}
}

执行go tool compile -S main.go > a

package main

const enable = true

func main() {
	if enable {
		println("hello word")
	}
}

执行go tool compile -S main.go > b

然后比较a,b的结果,可以明显看到当const enable = falseprintln("hello word")里面的常量字符串都不会编译到可执行程序中,所以我们可以放心使用编译优化这个功能完成条件编译。那些编译时就能计算出结果的if表达式大家可以放心编写相关逻辑,这个if是绝对不会在运行时去执行的。

只是麻烦的是代码中出现的函数,在两份条件编译文件里面都必须有声明,可以参考race.gonorace.go这两个文件的写法。

image

总结

有关条件编译的用法网上有很多资料,所以我这里主要研究条件编译原理,以及条件可以填写的所有值,和一些特殊的规则,这样在我编写相关条件时可以更加的心应手

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/83646.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Node.js计算机毕业设计道岔故障监测系统设计Express

项目运行 环境配置: Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境:最好是Nodejs最新版,我…

CSS -- 05. CSS定位方式总结

文章目录CSS定位1 定位1.1 为什么需要定位1.2 定位组成1.3 静态定位 static(了解)1.4 相对定位 relative(重要)1.5 绝对定位 absolute(重要)1.6 子绝父相1.7 固定定位 fixed(重要)1.…

SpringMVC(三) 获取请求参数(干货、超详细)

1.环境搭建 见SpringMVC(一) 2.获取参数 2.1使用Servlet API获取请求参数 将HttpServletRequest作为控制器方法的形参,DispatcherServlet发现控制器方法有HttpServletRequest形参,就把参数给传进来,HttpServletRequest就是javaWeb中的Htt…

[附源码]计算机毕业设计房屋租赁信息系统Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: Springboot mybatis MavenVue等等组成,B/S模式…

Python文件操作详解(一)

今天继续给大家介绍Python相关知识,本文主要内容是Python文件操作详解。 一、Python文件处理简介 使用Python可以编写程序处理文件,Python可以处理的文件值得是任何存储在辅助存储器上的数据序列。 在Python中,对于文件的处理通常由一定的流…

Code::Blocks(V20.03)工具安装、汉化、使用一条龙介绍

文章目录1、猿如意介绍2、Code::Blocks简介3、Code::Blocks安装3.1 下载3.2 安装3.3 汉化(可选项)4、Code::Blocks使用4.1 基本界面一览4.2 单个小工程5、Code::Blocks使用感受1、猿如意介绍 猿如意官网客户端下载地址 正如官网页面介绍猿如意的功能和作…

Allegro如何创建Group操作指导

Allegro如何创建Group操作指导 Allegro支持把器件,过孔和走线等等做成一个Group,对于PCB设计也很大帮助,如何创建一个group,具体操作如下 以下面图片为例 选择edit-groups Options选项里输出任意一个Group的名字 之后会出现一个Create Group弹窗,选择是 之后find选择…

年终将近,如何快速处理销售数据分析

编者按:如何做好企业销售数据分析,基于低代码平台实现的智能销售系统,以四大数据引擎为支撑,助力企业数据管理。 关键词:低代码平台,企业域管理,数据视图,智能报表,数据…

FFmpeg音视频编解码详解

本文你可以了解到 如何在 NDK 层调用 OpenGL ES ,以及使用 OpenGL ES 来渲染 FFmpeg 解码出来的视频数据。 一、渲染流程介绍 在 Java 层,Android 已经为我们提供了 GLSurfaceView 用于 OpenGL ES 的渲染,我们不必关心 OpenGL ES 中关于 EGL…

开发游戏相关业务该如何选择云服务器及相关产品?

游戏开发分为两种,第一种就是角色扮演类,另一种就是休闲类游戏,角色扮演类游戏对于计算能力以及游戏安全有很大的尤其;而休闲类游戏对于资源、运维、成本控制有所要求,下面就给大家展示一下腾讯云官方给出的解决方案&a…

如何去做一个完整的网站 SEO 优化方案?

想要做好网站优化,就必须制定一套适合自己的网站优化方案。优化只是一个过程,更多的是简单工作的重复,但也有技巧和方法。这个时候,你的网站优化方案就显得尤为重要。为您指明今后优化工作的途径,您在上一篇文章《传:东…

网络小白入门之路之以太网链路聚合 ---尚文网络奎哥

随着业务的发展和园区网络规模的不断扩大,用户对于网络的带宽、可靠性要求越来越高。传统解决方案通过升级设备方式提高网络带宽,同时通过部署冗余链路并辅以STP(Spanning Tree Protocol,生成树协议)协议实现高可靠。传…

使用Idea中Docker插件部署并远程Debug

目前在java开发中,由于一套完整的项目所涉及到的微服务模块很多,要是按照传统的方式一个一个部署比较麻烦,所以很多情况下我们都会使用docker镜像的方式进行部署。当我们的应用部署好之后,若运行过程中出现问题,我们也…

docker搭建服务监控 prometheus+node_export+grafana

文章目录下载镜像node-exporter 收集数据prometheus监控搭建grafana数据可视化下载镜像 docker pull grafana/grafana docker pull prom/node-exporter docker pull prom/prometheus链接:点击 提取码:yyds node-exporter 收集数据 docker run -d -p 9…

Android:为了突破瓶颈,你总得新学点什么吧?

一眨眼就到了12月份了,在这拥有“35岁魔咒”IT场上工作多年的你,是否遇到了发展瓶颈?想突破瓶颈有时需要一个机遇,但这个合适的机会很难遇到。这时候,或许你可以思考,自己是否还有改变的空间?如…

不会开赛车的管理者不是好的开发人

今天要讲述的人物,身上的标签比较多元。 他是微软 RD( Regional Director )兼微软 MVP;在制造业领域深耕十多年,擅长在不同的角色用不同观点看待软件开发流程,热爱探索商业需求和解决方案之间的平衡&#…

目标检测中的不均衡问题综述

导推荐的,简单看了一下,(太菜,太多不懂,希望以后会懂,简单做个记录 其实做的是xmind,但是想放到csdn上只能导出成md了。 Imbalance Problems in Object Detection: A Review 类别不平衡 简单…

01GO入门

GO入门一、hello,world二、运行一、hello,world 对上图的说明 1.go文件的后缀是.go 2.package main ​ 表示该hello.go 文件所在的包是main,在go中每个文件都必须归属于一个包。 3.import“fmt” ​ 表示:引入一个包&#xf…

【Docker】Docker镜像是什么?浅谈对Docker镜像的理解

专栏往期文章 《Docker是什么?Docker从介绍到Linux安装图文详细教程》《30条Docker常用命令图文举例总结》 本期目录专栏往期文章1. Docker镜像介绍2. UnionFS介绍3. Docker镜像加载原理4. 为什么Docker镜像要采用分层结构5. 镜像只读, 容器可写1. Docker镜像介绍 …

nodejs+vue社团管理系统

目录 1 绪论 1 1.1 课题背景 1 1.2 课题研究现状 1 1.3 初步设计方法与实施方案 2 1.4 本文研究内容 2 2 系统开发环境 4 开发语言:nodejs 框架:Express 数据库:mysql 数据库工具:Navicat11 开发软件&#x…