go 编译指令build

go:build 是 Go 1.17 版本中引入的一个构建标记,用于根据不同的条件控制代码的编译。go:build 格式如//go:build <标记表达式>, 1.17之前使用+build的方式,这里我们介绍更强大的的go:build. 表达式可以包含由 ||、&& 和 ! 运算符和括号组合的选项,含义与 Go 语言中相同. 构建约束可以出现在任何类型的源文件中(不仅仅是 Go 文件),但是它们必须出现在文件的顶部附近,仅由空行和其他行注释分隔。这些规则意味着在 Go 文件中,构建约束必须出现在包声明之前。 例如,下面的构建约束将约束一个文件在满足“linux”和“386”约束条件或在满足“darwin”条件且未满足“cgo”条件时进行构建://go:build (linux && 386) || (darwin && !cgo) 自定义tag //go:build atest 当我们使用go build -tags atest的情况下会编译此文件,否则不会编译 控制go版本 //go:build go1.17 指定当前文件>=go1.17才编译 //go:build go1.17 && go1.20 版本>= go1.17 并且<= go1.20

<span title='2023-03-07 10:50:47 +0800 +0800'>三月 7, 2023</span>

go 编译指令Linkname

go:linkename是go的编译指令,可以在一个包中使用另一个包中的非导出函数或变量 具体使用方法举例 在pkg1包中有个未导出的函数add package pkg1 func add(a, b int) int { return a + b } 在pkg2中想要使用pkg1.add,正常来说add开头是小写是不能被另一个包使用的,这时候我们想要在另一个包中使用就有两种方法: 在pkg1中定义一个可以导出的函数,这种就是在写个Add函数包裹一下,这种就不举例了 在pkg2中使用linkname编译指令修改函数或变量的名称和可见性(不太建议) 这里我们举例第二种 package pkg2 import ( _ "goasm/pkg1" //需要引入pkg1, 让pkg1参与代码编译,否则编译器找不到, 这句也可以写在别的文件中,只要让pkg1参与编译就行, relocation target goasm/pkg1.add not defined _ "unsafe" //编译器要求导入unsafe包,否则不能使用linkname指令 ) //下面就是linkname编译指令使用方法, 在函数声明上添加注释, 其中pkg1_add是函数名称, goasm/pkg1.add 是要连接的函数, 这句指令的效果就是,调用pkg1_add就是在调用goasm/pkg1包中的add函数 //go:linkname pkg1_add goasm/pkg1.add func pkg1_add(a, b int) int func Add2(a, b int) int { return pkg1_add(a, b) } 总结: go:linkname的使用是依赖于编译器的实现,因此使用时需要慎重考虑其可维护性和可移植性。 总之了解就好,不是迫不得已不要真的使用

<span title='2023-02-24 14:35:25 +0800 +0800'>二月 24, 2023</span>