为什么选择Go

shiyd, Go
Back

直接编译成二进制,没有虚拟化损失;自带运行环境,无需处理GC问题;一次编译可以适用多种平台;超强的并发支持和易用性。

何为Runtime?

runtime就是程序的运行环境,作为程序的一部分打包进二进制产物。随用户程序一起运行,与用户程序没有明显界限,直接通过函数调用。

go的runtime负责内存管理,垃圾回收,协程调度。runtime的能力:

Go的编译过程

首先是执行 compile.exe 生成.a 文件,然后执行 link.exe。

词法分析→句法分析→语义分析 →中间码生成 →代码优化 →机器码生成 →链接(将各个包进行链接)

词法分析:

package main

import "fmt"

fun main(){
	fmt.Println("hello, 世界")
}

句法分析:

语义分析:

中间码生成:

# win
env:GOSSAFUNC="main"
# linux
export GOSSAFUNC=main
# build 后生成一个ssa.html 文件
go build

机器码生成

查看Plan9汇编代码:

go build -gcflags -S main.go

链接

将各个包进行链接,包括runtime

Go语言是如何运行的?

Go程序的入口不是main,而是runtime/rt0_XXX.s。不管是win还是linux都要走 _rt0_amd64(SB) 这个方法。

1、读取命令行参数:复制参数数量argc和参数值argv到栈上

2、初始化g0执行栈:g0是为了调度协程而产生的协程,g0是每个Go程序的第一个协程。

3、运行时检测:检查各种类型长度,检查指针操作,检查结构体字段偏移量,检查atomic原子操作,检查CAS操作,检查栈大小是否是2的幂次。

4、初始化runtime.args:对命令行的参数进行处理,参数数量赋给argc int32,参数值复制给argv **byte

5、调度器初始化 runtime.schedinit:全局栈空间内存分配;加载命令行参数到 os.Args;堆内存空间的初始化;加载操作系统环境变量;初始化当前系统线程;垃圾回收器的参数初始化;算法初始化(map,hash);设置process数量

6、创建主协程:创建一个新的协程,执行runtime.main

7、初始化M:初始化一个M,用来调度主协程

8、主协程执行主函数:执行runtime包中的init方法;启动垃圾收集器,执行用户包依赖的init方法,执行用户主函数 main.main()

Go是面向对象的语言吗

Go 没有对象,没有继承、没有实现、没有类。而是通过组合匿名字段达到类似的效果。

Go允许OO编程风格,Go的struct可以看作其他语言的class,Go缺乏其他语言的继承结构,Go的接口和其他语言有很大差异。

在其他语言中,往往用class表示一类数据,class的每个实例称作“对象”,Go是使用Struct表示一类数据,Struct每个实例并不是对象,而是此类型的值,Struct也可以定义方法。

Go并没有继承,而是组合。组合中的匿名字段,通过语法糖达成类似继承的效果。

package main

type Main struct{
	People
}

type People struct{	
}

func (p People) walk() {
	fmt.Println("walk")
}

func main(){
	m:=Main()
	m.walk() // m.People.walk()
}

Go 的接口,接口可以定义Go中一组行为相似的struct,struct并不是显示的实现接口,而是隐士的实现接口。

Go 项目包管理方法

之前的使用的是godep、govendor、golide解决。现在使用的Go Modules

Go vender缓存到本地:

go mod vender
go build -mod vendor

如何创建Go Moody

© shiyd.RSS