一、Go语言调试
- 编译过程
- 将 Go 语言的源代码编译成汇编语言,然后通过汇编语言分析程序具体的执行过程
go build -gcflags -S main.go
二、切片使用
1、取数组的一段
package main
import (
"fmt"
)
func main() {
a := []int{1, 2, 3, 4, 5}
var qp []int = a[0:3]
fmt.Println(qp)
}
//[1 2 3]
2、一个切片是一个数组片段的描述。它包含了指向数组的指针,片段的长度, 和容量(片段的最大长度)。
3、更改切片的元素会修改其底层数组中对应的元素。与它共享底层数组的切片都会观测到这些修改。
4、在进行切片时,可以利用它的默认行为来忽略上下界,默认(第一个元素到最后一个元素)
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
s = s[1:]
fmt.Println(s)
s = s[:2]
fmt.Println(s)
s = s[1:]
fmt.Println(s)
}
/*
[3 5 7 11 13]
[3 5]
[5]
*/
5、切片 s 的长度和容量可通过表达式 len(s) 和 cap(s) 来获取,切片的长度就是它所包含的元素个数。切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。
6、切片的零值是 nil,nil 切片的长度和容量为 0 且没有底层数组。
package main
import "fmt"
func main() {
var s []int
fmt.Println(s, len(s), cap(s))
if s == nil {
fmt.Println("nil!")
}
}
/*
[] 0 0
nil!
*/
7、切片可以用内建函数 make 来创建,make 函数会分配一个元素为零值的数组并返回一个引用了它的切片,创建切片时需要指定长度和容量
package main
import "fmt"
func main() {
a := make([]int, 5)//一定要指定长度,不然会报错
printSlice("a", a)
b := make([]int, 0, 5)
printSlice("b", b)
c := b[:2]
printSlice("c", c)
d := c[2:5]
printSlice("d", d)
}
func printSlice(s string, x []int) {
fmt.Printf("%s len=%d cap=%d %v\n",
s, len(x), cap(x), x)
}
/*
a len=5 cap=5 [0 0 0 0 0]
b len=0 cap=5 []
c len=2 cap=5 [0 0]
d len=3 cap=3 [0 0 0]
*/
8、Go的数组是值语义。一个数组变量表示整个数组,它不是指向第一个元素的指针(不像 C 语言的数组)。 当一个数组变量被赋值或者被传递的时候,实际上会复制整个数组。 (为了避免复制数组,你可以传递一个指向数组的指针,但是数组指针并不是数组。) 可以将数组看作一个特殊的struct,结构的字段名对应数组的索引,同时成员的数目固定。
9、切片操作并不会复制底层的数组。整个数组将被保存在内存中,直到它不再被引用。 有时候可能会因为一个小的内存引用导致保存所有的数据,而不能gc回收。
10、for 循环的 range 形式可遍历切片或映射。每次迭代都会返回两个值。第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本。
package main
import "fmt"
func main() {
s := []int{1, 2, 3}
for i, v := range s {
fmt.Println(i, v)
}
}