数组
数组定义:
var 数组名 [数组大小]数据类型
初始化方式:
var nums [3]int = [3]int{1,2,3}
var nums = [3]int{1,2,3}
var nums = [...]int{4,5,6}
- 数组的地址可以通过数组名来获取 &intArr
- 数组第一个元素的地址就是数组的首地址
func main(){
var IntArr [3]int
IntArr[0] = 1
IntArr[0] = 31
IntArr[0] = 6
fmt.Println(IntArr)
fmt.Printf("%p\n",&IntArr)
fmt.Println(&IntArr[0])
}
[6 0 0]
addr:0xc00000c1e0
0xc00000c1e0
遍历方式:
-
常规方式
var IntArr [3]int = [3]int{4,5,6} for i := 0;i < len(IntArr);i++{ fmt.Println(IntArr[i]) }
-
for-range结构遍历
for i,val := range IntArr{ //i 和 val都是仅再for循环内部可见的局部变量 fmt.Println(i,val) }
数组使用注意事项:
- 一个数组一旦声明了,长度是固定的,不能动态变化
- 数组属性类型,默认是值类型
二维数组使用方式:
-
先声明/定义,在赋值
func main(){ var arr2 [2][3]int arr2[1][1] = 12 arr2[0][1] = 13 fmt.Println(arr2) fmt.Printf("arr[0]地址:%p\n",&arr2[0]) fmt.Printf("arr[1]地址:%p\n",&arr2[1]) fmt.Printf("arr[0][0]地址:%p\n",&arr2[0][0]) fmt.Printf("arr[1][0]地址:%p\n",&arr2[1][0]) }
[[0 13 0] [0 12 0]]
arr[0]地址:0xc0000103f0
arr[1]地址:0xc000010408
arr[0][0]地址:0xc0000103f0
arr[1][0]地址:0xc000010408内存分布情况:
-
直接初始化
var arr1 [2][3]int = [2][3]int{{1,2,3},{4,5,6}} var arr2 [2][3]int = [...][3]int{{1,2,3},{4,5,6}} var arr3 = [2][3]int{{1,2,3},{4,5,6}} var arr4 = [...][3]int{{1,2,3},{4,5,6},{2,4,6}}
二维数组的遍历:
func main(){
var arr = [...][3]int{{1,2,3},{4,5,6},{2,4,6}}
fmt.Println(arr)
for i,v := range arr{
for j,v2 := range v{
fmt.Printf("arr[%v][%v]=[%v] \t",i,j,v2)
}
fmt.Println()
}
}
切片
注意事项:
-
slice是一个引用类型
-
从底层来说,切片是一个结构体
type slice struct{ ptr *[2]int len int cap int }
切片的使用:
-
利用一个已经创建好的数组来创建切片
var IntArr [3]int = [3]int{4,5,6} var sl = IntArr[:] //var slice = arr[startindex:endindex](不含endindex的元素) for _,val := range sl{ fmt.Println(val) }
-
通过make来创建切片
var sl2 []float64 = make([]float64,5,10) sl2[0] = 10 sl2[3] = 90 fmt.Println(sl2)
- 通过make方式可以指定切片的大小和容量
- 如果没有给切片元素赋值,默认值为0
- 通过make创建的切片对应的数组是由make底层维护的,对外不可见
-
直接定义一个切片
var sl3 []string = []string{"ajs","asdu","asdhas"} for _,val := range sl3{ fmt.Println(val) }
切片使用注意事项:
-
切片可以继续切片
-
使用append内置函数可以对切片进行动态追加
var sl2 []float64 = make([]float64,5,10) sl2[0] = 10 sl2[3] = 90 var sl3 []float64 = []float64{23,4,234,3} sl3 = append(sl3,123,34) fmt.Println(sl3) sl3 = append(sl3,sl2...) fmt.Println(sl3)
-
可以使用copy对切片进行拷贝,新生成的切片和原来的切片数据空间是独立的,相互不影响。
string和slice
Go语言的string底层其实是一个byte类型的数组,因此string也可以进行切片处理
string和切片在内存的形式:
func main(){
var str string = "abcd"
mslice := str[1:]
fmt.Println(mslice)
fmt.Printf("%T",mslice)
}
bcd
string
我们需要注意string是不可变的,也就是不能通过str[0]= 'a'
来修改字符串,那么就不能修改了吗?可以,不过需要将其转化为[]byte或者[]rune,然后再转写成string
func main(){
var str string = "abcd"
bytearr := []byte(str)
bytearr[0] = 'z'
str = string(bytearr)
fmt.Println(str)
runearr := []rune(str)
runearr[0] = '哈'
str = string(runearr)
fmt.Println(str)
}
zbcd
哈bcd
这里有一个小细节,我们转[]byte后,不可以处理中文,因为[]byte是按着字节来处理,而一个汉字是3个字节,此时需要用[]rune