Golang内部构件,第2部分:深入Go编译器

Posted xxx小M

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang内部构件,第2部分:深入Go编译器相关的知识,希望对你有一定的参考价值。

通过接口引用使用变量时,您是否知道Go运行时中到底发生了什么? 这不是一个小问题,因为在Go语言中,实现接口的类型不包含对该接口的任何引用。 尽管如此,我们仍可以尝试使用我们对Go编译器的知识来回答它,这在上一篇博客文章中已经讨论过。

因此,让我们深入研究Go编译器:创建一个基本的Go程序,并查看Go类型转换的内部工作原理。 以它为例,我们将解释如何生成和利用节点树。 因此,您可以进一步将此知识应用于其他Go编译器的功能。

在你开始之前

为了进行实验,我们需要直接使用Go编译器(而不是Go工具)。 您可以使用以下命令访问它。

go tool 6g test.go

它将编译test.go源文件并创建一个目标文件。 在这里,6g是我们计算机上具有AMD64架构的编译器的名称。 请注意,对于不同的体系结构,应使用不同的编译器。

当我们直接使用编译器时,我们可以使用一些方便的命令行参数(更多详细信息在官方文档中)。 为了本实验的目的,我们需要-W标志,该标志将打印节点树的布局。

创建一个简单的Go程序

首先,我们将创建一个示例Go程序。 您将在下面找到我们的版本。

package main
type I interface {
   DoSomeWork()
}
type T struct {
   a int
}
func (t *T) DoSomeWork() {
}
func main() {
   t := &T{}
   i := I(t)
   print(i)
}

真的很简单,不是吗? 唯一似乎不必要的是第17行,我们在其中提供了i变量。 但是,如果没有它,我将保持不使用状态,并且该程序将不会编译。 下一步是使用-W开关编译程序。

go tool 6g -W test.go

完成此操作后,您将看到包含程序中定义的每个方法的节点树的输出。 在我们的情况下,这些是main和init方法。 后者在这里,因为它是为所有程序隐式定义的,但实际上我们现在不在乎。

对于每种方法,编译器都会打印两个版本的节点树。 第一个是我们在解析源文件后获得的原始节点树。 第二个是我们经过类型检查并应用了所有必要修改后得到的版本。

以上是关于Golang内部构件,第2部分:深入Go编译器的主要内容,如果未能解决你的问题,请参考以下文章

Golang内部构件,第3部分:链接器,目标文件和重定位

Golang内部构件,第5部分:运行时引导程序

Golang内部构件,第4部分:目标文件和函数元数据

Golang内部构件,第6部分:自举和内存分配器初始化

golang学习笔记:安装&helloworld

Golang 对于 DevOps 之利弊(第 1 部分,共 6 部分):Goroutines, Panics 和 Errors