tour of go day1
起因是本来花了好几天折腾好了libbpf的交叉编译环境,结果用libunwind用的是bionic-libc,libbpf用的是glibc,尝试用ndk编译libbpf始终无法成功,只能尝试切换到go/cilium生态,然后把libunwind用cgo的形式添加到项目中
tour of go链接
go的软件都以包的形式存在,程序的入口点是main
包,包名定义在程序开头
1 | package main |
go的依赖导入使用import
,有两种写法
1 | import "math" |
1 | import( |
go中符号的导入导出依赖于命名约定,大写字母开头 的符号是导出的,否则不导出
声明变量
go的变量类型是定义在变量名之后的(类似ts但是不带:),通过空格隔开,如果指定了初始值可以自动推导类型
1 | var a int |
1 | func test(x int,y int) int { |
go的函数可以返回多个返回值(可能是用了类似打包解包的写法)
1 | func swap(x int,y int) (int,int){ |
go的多个变量在一行中初始化只能把变量名全写在左边,初始值全写在右边
1 | var x=1,y=2 // wrong! |
go可以使用短变量赋值写法简化变量定义,但是短变量赋值只能在函数内部使用
1 | a:=10 // var a=10 |
基本类型
go有以下几种基本类型
1 | bool |
其中uint
,int
,uintptr
位数和操作系统位数相同,其他类型都是定长类型
go中的零值有0
,false
,""
,nil
,未初始化的变量会被自动赋予对应类型的零值
类型转换
go中没有隐式类型转换,通过type()
的方式进行类型转换
1 | var i int = 42 |
常量使用const
声明,和变量唯一的区别就是不能使用:=
简写声明
循环
go语言中只有for
一种循环,除了没有小括号和必须加大括号外其他和c完全一样
1 | func main() { |
如果只有循环条件的话两个;
也可以不写,此时就和while
没什么区别了
1 | func main() { |
if
go的if
也是不用写括号,可以在条件之前执行一句初始化语句
1 | func pow(x, n, lim float64) float64 { |
初始化语句的生命周期限制在if
分支内和同级的else
分支内
switch
switch
在书写上也和if
类似,go
中的switch
默认执行完第一个匹配的分支就会终止,除非在分支结尾加上fallthrough
1 | switch os := runtime.GOOS; os { |
go中switch
的case
不限定为数字和常量,可以是任何值或变量甚至表达式,在运行时从上往下逐个匹配
switch
正常是以表达式的结果作为分支的判断标准,这里有一种switch true
的语法糖
1 | func main() { |
这样可以让一大串if else
更加清楚
defer
defer
是go的一种特性,带defer
修饰的语句其参数会正常求值,但调用会在函数返回才时执行
这个延迟采用栈结构,最先遇到的defer
语句最后执行
1 | func main() { |
指针
go中的指针也是类型名前加*
,也就是*Type
引用解引用都和c一样,但是没有指针运算
1 | func main() { |
结构体
结构体采用c风格定义,通过.
号访问成员,并支持{}
初始化
1 | type Vertex struct { |
与c中访问结构体指针的成员时需要通过->
不同,go中仍然使用.
,这里是自动做了解引用操作
支持具名变量形式初始化,未显式初始化的成员就初始化为零值
1 | v2 = Vertex{X: 1} |
数组
数组通过[]T
定义
1 | func main() { |
结构体传参是深拷贝,直接构造新对象,数组传参也是深拷贝,切片传参因为本身有引用性质所以是浅拷贝
切片
go中的数组支持切片
1 | a[low : high] |
这个区间是左闭右开的,也就是[low,high)
,这个上下界也是可以省略的,和python一样分别默认值是0和数组长度
切片本身是一块 引用 多块切片可以共享一个数组所拥有的一片内存
切片同样可以作为右值,[]bool{true, true, false}
等价于创建了一个[3]bool{true, true, false}
,然后再构造一个指向它的切片
切片对应的零值是nil
即空指针
切片的长度可以动态修改,分别可以根据len()
和cap()
两个函数获取切片的长度和容量
长度就是切片实际上包含的元素数,容量指的是从切片的第一个元素开始,一直到其所指向数组的末尾的元素数
切片的右端点可以左右移动,但是 左端点只能往右移动
也就是说s=[2:]
会让s永久失去对其前两个元素的访问权
可以使用make([]T,len,cap)
创建切片,三个参数分别是数组类型,长度,容量,这也是go指定的创建动态数组的方式(但是切片本身可以使用右值创建,而且切片的容量是可以自动拓展的,不理解make
的意义是什么)
tour of go day1