go语言基础查漏补缺
前几天刷题,虽然简单题会做,但是写的方法和格式过于复杂,还是得再把go的基础过一遍,查漏补缺。 以下内容整理自Go 语言之旅 (go-zh.org)
defer
defer 语句会将函数推迟到外层函数返回之后执行。
推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用
如下
感觉,可能会在倒序中有比较好的用途。下图所示:
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
会输出9 8 xxx
指针
Go 也拥有指针。指针保存了值的内存地址。
类型 *T 是指向 T 类型值的指针。其零值为nil。
var p *int & 操作符会生成一个指向其操作数的指针。
i := 42 p = &i
*操作符表示指针指向的底层值。
fmt.Println(*p) // 通过指针 p 读取 i
*p = 21 // 通过指针 p 设置 i
这也就是通常所说的“间接引用”或“重定向”。
但与 C 不同的点在于,Go 没有指针运算。
结构体
7.19日的每日一题就碰见了构建结构体的方法。(将索引和值都放在一个结构体中存储)
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X)
}
访问是通过 . 来进行,和c语言一样。
数组
类型 [n]T 表示拥有 n 个 T 类型的值的数组。
表达式
var a [10]int
会将变量 a 声明为拥有 10 个整数的数组。
数组的长度是其类型的一部分,因此数组不能改变大小。这看起来是个限制,不过没关系,Go 提供了更加便利的方式来使用数组。
直接声明是无法改变大小的,前面刷leetcode就踩坑了。
用 make 创建切片
切片可以用内建函数 make 来创建,这也是你创建动态数组的方式。
make 函数会分配一个元素为零值的数组并返回一个引用了它的切片:
a := make([]int, 5) // len(a)=5
要指定它的容量,需向 make 传入第三个参数:
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4
向切片追加元素 使用append函数
append 的第一个参数 s 是一个元素类型为 T 的切片,其余类型为 T 的值将会追加到该切片的末尾。
append 的结果是一个包含原切片所有元素加上新添加元素的切片。
当 s 的底层数组太小,不足以容纳所有给定的值时,它就会分配一个更大的数组。返回的切片会指向这个新分配的数组。
举例:
func main() {
var s []int
printSlice(s)
// 添加一个空切片
s = append(s, 0)
printSlice(s)
// 这个切片会按需增长
s = append(s, 1)
printSlice(s)
// 可以一次性添加多个元素
s = append(s, 2, 3, 4)
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
输出
len=0 cap=0 []
len=1 cap=1 [0]
len=2 cap=2 [0 1]
len=5 cap=6 [0 1 2 3 4]
注:cap作用
切片是可索引的,并且可以由 len () 方法获取长度。 切片提供了计算容量的方法 cap () 可以测量切片最长可以达到多少。
循环
我刷题用的一般都是最普通的for循环,然后 依次初始化,判断条件,条件满足后的操作 三部。
但是也可以用range来遍历
当使用 for 循环遍历切片时,每次迭代都会返回两个值。第一个值为当前元素的下标,第二个值为该下标所对应元素的一份副本。
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
}
输出
2**0 = 1
2**1 = 2
2**2 = 4
2**3 = 8
2**4 = 16
2**5 = 32
2**6 = 64
2**7 = 128
也可以值赋予 _ 来忽略它。
for i, _ := range pow
for _, value := range pow
若你只需要索引,忽略第二个变量即可。
for i := range pow
如例题:
func main() {
pow := make([]int, 10)
for i := range pow {
pow[i] = 1 << uint(i) // == 2**i
}
for _, value := range pow {
fmt.Printf("%d\n", value)
}
}
输出
1
2
4
8
16
32
64
128
256
512