一、数组
说明数组是值类型,其他语言是引用类型,类似 var a int = 10 内存分布
1.数组的地址可以通过数组名获取 &arr
2.数组第一个元素的地址是数组的首地址
3.数组各元素的地址间隔依据数组的类型决定
4.数组长度固定,不能动态变化
5.数组创建后,数值类型默认0,字符串默认“”,bool数组默认false
6.数组作为参数传递时,需要注意参数的长度,一定要与之对应
func main(){
//定义并初始化数组的几种方式
var arr [3]int //默认数组元素为0
var arr[0] = 10
var arr0 [3]int = [3]int{1, 2, 3}
var arr1 = [3]int{5, 6, 7} //利用类型推倒
var arr2 = [...]int{8, 9, 10}
var arr3 = [...]int{1: 100, 0: 500, 2: 999}
fmt.Println(arr0, arr1, arr2, arr3)
//遍历数组两种方式
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
for index, value := range arr { //下标和值
fmt.Println(index, value)
}
//修改数组注意事项
test1(arr)
fmt.Println("arr=", arr)
test2(&arr)
fmt.Println("arr=", arr)
}
//数组属于值类型,默认是值传递,因此进行值拷贝,数组间不会影响
func test1(arr [3]int) {
arr[0] = 88
}
func test2(arr *[3]int) {
(*arr)[0] = 88
}
二、切片
1.切片是一个引用类型,切片的长度是可以变化的,而数组的长度是固定的
2.切片是数组的一个引用,因此是引用类型,遵守引用传递机制
3.切片的使用和数组类似,比如遍历切片,访问切片的元素等
4.通过make创建切片对应数组由make底层维护,对外不可见
package main
import "fmt"
func main() {
var arr = [5]int{1, 23, 34, 66, 43}
//定义一个切片,让切片引用一个已创建好的数组
//表示 slice 引用到 arr 这个数组
//引用范围数组下标[1,3)
slice := arr[1:4] //[:]代表全部,[start:]代表开始到结束
fmt.Println(slice)
fmt.Println("容量 =", cap(slice)) //一般为切片元素个数的2倍,可动态变化
//第二种方式使用make
var slice1 = make([]float64, 5, 10) //必须为[],参数为数据类型,大小,容量
fmt.Println(slice1)
//第三种方式,原理类似make
var slice2 = []int{1, 2, 3}
fmt.Println(slice2)
//遍历切片
for i := 0; i < len(slice); i++ {
fmt.Println(slice[i])
}
for i, v := range slice {
fmt.Printf("i = %v,v = %v\n", i, v)
}
//切片的动态追加,底层原理是新建数组,然后切片指向新的数组
slice = append(slice, 88, 99)
fmt.Println(slice)
//切片拷贝
slice3 := make([]int, 10)
copy(slice3, slice) //把slice拷贝给slice3,必须是切片类型才可以
fmt.Println(slice3)
//字符串与切片之间的关系
str := "hello@go中"
//string底层是一个数组,因此string可以进行切片
//string是不可变的,因此不能用string[0]修改字符串
//如果修改string,将string转成[]byte或[]run(字符处理兼容汉字)切片
slice4 := str[6:]
arr1 := []rune(str)
arr1[8] = '国'
str = string(arr1)
fmt.Println(slice4)
fmt.Println(str)
}
三、二维数组
package main
import "fmt"
func main() {
var arr = [4][6]int{} //4个含有6个元素的一维数组
arr[0][0] = 10
arr[2][3] = 20
fmt.Println(arr)
//声明 并初始化
var arr1 = [2][3]int{{10, 12, 23}, {23, 45, 56}}
fmt.Println(arr1)
//二维数组遍历
for i := 0; i < len(arr1); i++ {
for j := 0; j < len(arr1[i]); j++ {
fmt.Printf("%v\n", arr1[i][j])
}
}
for i, v := range arr1 { //v 是一维数组
for i2, i3 := range v { //遍历一维数组
fmt.Printf("arr1[%v][%v]=%v\t", i, i2, i3)
}
}
}
四、map
1.map 是引用类型,遵守引用类型传递机制,修改后会影响原来的map
2.map 容量满后,可以自动扩容,增加key-value不会报错
package main
import (
"fmt"
"sort"
)
func main() {
//声明map并不会分配内存
var a map[string]string
//使用map前需要make,make的作用就是给map分配内存空间
a = make(map[string]string, 10) //10:创建长度
a["no1"] = "宋江"
a["no2"] = "吴用"
a["no3"] = "卢俊义"
a["no3"] = "武松"
fmt.Println(a)
//声明并初始化
var heroes = map[string]string{"hero1": "刘备",
"hero2": "关羽",
"hero3": "张飞"}
fmt.Println(heroes)
//value是map
student := make(map[string]map[string]string) //空间大小不写也可以
student["01"] = make(map[string]string)
student["01"]["name"] = "tom"
student["01"]["sex"] = "男"
student["02"] = make(map[string]string)
student["02"]["name"] = "jack"
student["02"]["sex"] = "女"
fmt.Println(student)
//增删改查
heroes["hero4"] = "吕布" //如果key存在则是增加,否则为修改
delete(heroes, "hero4") //如果key不存在,删除不会操作,也不会报错
//一次性删除所有的key,可遍历key删除,可创建新的空间
heroes = make(map[string]string) //推荐
val, findRes := a["no2"] //val是key对应的值,findRes 为是否存在key
if findRes {
fmt.Printf("key的值为%v\n", val)
}
//遍历map,只能用for-range,无序输出
for s, s2 := range a {
fmt.Printf("key=%v,value=%v\n", s, s2)
}
for s, m := range student {
fmt.Println("key=", s)
for s2, s3 := range m {
fmt.Printf("\tkey=%v,value=%v\n", s2, s3)
}
}
//map的长度,有多少对key-value
fmt.Println("map 的长度", len(a))
//map切片,可以理解为数组元素为map,可以动态增加map
monster := make([]map[string]string, 2)
if monster[0] == nil {
monster[0] = make(map[string]string)
monster[0]["name"] = "牛魔王"
monster[0]["age"] = "400"
}
if monster[1] == nil {
monster[1] = make(map[string]string)
monster[1]["name"] = "狮子精"
monster[1]["age"] = "300"
}
newMonster := map[string]string{"name": "白骨精", "age": "500"}
monster = append(monster, newMonster)
fmt.Println(monster)
//按照map的key的顺序进行排序输出
map1 := map[int]int{15: 14, 67: 23, 34: 45, 20: 11}
keys := []int{}
for key, _ := range map1 { //创建切片将key存入切片
keys = append(keys, key)
}
sort.Ints(keys) //递增顺序排列
for _, key := range keys {
fmt.Printf("map[%v] = %v\n", key, map1[key])
}
}