一些感想。。。
学习go的第一天,感觉python把我惯坏了,真实的编程世界是很残酷的。但是还是要努力学下去啊!加油鸭!!
老老实实的记笔记,数据类型比python复杂多了,写法都记了半天,定义的时候记住数字优先然后类型。
提醒一下,所有的语句都要放在函数内部,函数要放在package main里,并且package里要有main函数,下面开始正文吧
数组
声明和初始化:
原则:1. 数组长度 2. 存储数据类型(必须以一致)1
2
3
4
5
6
7
8
9
10
11
12var array [5]int //初始化全0
array:= [5]int{1,2,3,4,5} //非零初始化
array:=[...]int{1,2,3} //可以不声明长度,go会自动计算长度
array:=[5]int{1:3,2:4} //只初始化个别位置,其他为0
array[1]=5 //修改数组元素
fmt.Printf("%d\n",array[1])
//循环打印数组的值
func main() {
for i,v := rang array{
fmt.Printf("索引:%d,值:%d\n",i,v)
}
}
数组赋值:只有长度相同,每一个元素类型都相同的数组可以互相赋值。1
2array := [3]int{1,2,3}
array1 = array
指针数组:指针数组的初始化可以用new(int),new(bool),new(string),分配各种类型的内存空间,int初始值为0,str空,bool false1
2
3
4
5i = new(int) //返回的是为整型分配的地址,*i 指的是值为0,相当于i就变成指针
*i= 5 //给指针指向的地址赋值
p := [8]*int{1:new(int),2:new(int)} //没设初值的为指针的零值nil
*p[1] = 9 //只能给设了初值的赋值,因为只有他们分配了内存地址
fmt.Println(*p[1])
下面用指针完成数组复制:1
2
3
4
5
6
7
8
9
10func main(){
array:= [3]int{1,2,3}
modify(&array) //将array的指针传入modify,函数外部&表示值,*表示指针,内部相反
fmt.Println(array)
}
func modify(a *[3]int){
a[1] = 5
fmt.Println(*a) //*a指的是数组的值,因为a是当地址传入的
}
切片
切片的底层是数组,动态数组。有三个字段的数据结构:指向底层数组的指针,切片的长度,切片的容量。
切片的声明和初始化:
声明切片长度>=容量的切片使用make(),不能设初值:
1
2slice := make([]int,5) //如果只有一个参数。默认长度容量都是5
slice := make([]int,5,10) //长度5,容量10,但是能访问的只有5,剩下的自动扩容后才能访问切片长度==容量:
1
2
3
4
5
6//切片
slice := []int{1,2,3} //长度容量都是3,也设置了初值
slice := []int{1:2,4:5} //长度容量都是5
//切片和数组的区别
array := [5]int{0,1,2,3,4} //数组需要设置长度nil切片和空切片:nil切片意味着指向底层数组的指针为nil,而空切片对应的指针是个地址。
1
2var nilSlice = int[] //nil切片
Slice := []int{} //空切片切片切片:长度为k的切片切片赋值给新切片slice[i:j], 新切片和原始切片都指向同一个底层数组,一个变大家都变。
新切片的长度:j-i,容量:k-i。slice[i:j:k]这种设置间隔的也一样计算。1
2
3slice1 := []int{0,1,2,3}
slice2 := slice[1:2] //只包含头不包含尾
slice3 := slice[:]
使用切片
1.append
切片也可以通过索引获取,修改值。还可以通过append追加值。但是由于slice,newslice都指向同一个底层数组,而append操作是对底层数组的操作,所以旧slice也会受影响1
2
3
4
5slice := []int{0,1,2,3,4}
newslice := slice[2:4]
newslice = append(newslice,10) //append并不会修改newslice的值,而是重新复制一个,我们把它再次赋值给newslice,这才改变newslice,但所有的slice都指向同一个底层数组
fmt.Println(slice) //[0,1,2,3,10] 由于newslice指向的底层数组还有空间,所以底层数组的第四位就被重新赋值了
fmt.Println(newslice)//[2,3,10]
如果底层数组没有了多余空间,执行append的时候,会先把底层数组赋值给具有足够容量的新数组,然后对新数组执行append操作,这样就完全不会影响以前的引用了。1
2
3
4
5slice := []int{0,1,2,3,4}
newslice := slice[2:]
newslice = append(newslice,10)
fmt.Println(slice) //[0,1,2,3,4]
fmt.Println(newslice) //[2,3,4,10]
append也可以追加好几个值。append会智能的增长底层数组的容量,目前的算法是,容量小于1000时,成倍增长,大于1000,1.25倍增长
此外还可以通过…把一个切片追加到另一个切片里:1
new = append(slice, newslice...)
迭代 for
1
2
3
4
5
6func iter(){
slice := []int{1,2,3,4}
for i,v := rang slice {
ftm.Println(v)
}
}最后由于切片是一个只有三个字段的数据结构在函数间传递,所以是很高效的!不过,在函数间的传递是复制后传递的,因为两个变量地址不同,但如果改一个,大家都要变,所以还是共享一个底层数组。