Golang切片(slice)和映射(map)学习笔记

        本文是对golang切片(slice)和映射(map)的学习笔记。包含定义、基础语法、遍历及基本操作和注意事项等。

目录

切片(slice)

切片的定义

切片的基本语法

切片的遍历 

切片的注意事项

映射(Map)

映射的定义 

基本语法

特点 

 相关操作

加深难度


切片(slice)

切片的定义

        是对数组的一个连续片段的引用,所以切片是一个引用类型。这个片段可以是整个数组,或者是由起始和终止索引标识的一些项的子集。注意:终止索引标识的项不包括在切片内。切片提供了一个动态窗口。

        建立在数组(长度固定不变)之上的抽象,并且提供更强大的能力和便捷。

        是golang的一种特有的数据结构

切片的基本语法

1、定义一个切片,然后让切片去引用一个已经创建好的数组基本语法:

                                        var 切片名 []类型 = 数组的一个片段引用                             

var intarr [6]int = [6]int{3, 6, 9, 1, 4, 7}
var slice []int = intarr[1:3]

 2、通过make内置函数来创建切片。基本语法:

                                        切片名 := make([]类型,长度,容量)                             

//定义切片:make函数的三个参数:1、类型2、长度3、容积
Slice := make([]int,4,20)   //[0,0,0,0]
Slice[0] = 6
Slice[1] = 8     //[6,8,0,0]

make在底层创建一个数组,对外不可见,不可直接操作/维护这个数组,要通过slice                      切片去间接的访问各个元素。

3、定义一个切片,直接就指定具体数组(对外不可见),使用原理类似make的方式。

                                        Slice := []int{1,4,7} 

func main() {
	//定义数组
	var intarr [6]int = [6]int{3, 6, 9, 1, 4, 7}
	//切片构建在数组之上
	//定义一个切片slice,[]动态变化数组长度不写,int类型,intarr是原数组
	//[1:3]切片 - 切出的一段片段 - 索引:从1开始,到3结束(不包含3)
	var slice []int = intarr[1:3]    //前包括后不包括
	fmt.Println(intarr)
	fmt.Println(slice)
//切片元素个数
fmt.Println(len(slice))
//获取切片的容量:容量可以动态变化
fmt.Println(cap(slice))
}

        切片有三个字段的数据结构(结构体):一个是指向底层数组的指针,一个是切片的长度,一个是切片的容量。 

        通过切片可以更改原数组里面的值。 

切片的遍历 

func main() {
	var intarr [6]int = [6]int{3, 6, 9, 1, 4, 7}
	var slice []int = intarr[1:5]
	//方式1:普通for循环
	fmt.Println("for循环遍历:")
	for i := 0; i < len(slice); i++ {
		fmt.Printf("slice[%v] = %v \t",i,slice[i])
	}
	//方式2:for-range循环
	fmt.Println("\n for-range循环遍历:")
	for i,v := range slice {
		fmt.Printf("slice[%v] = %v \t",i,v)
	}
}

切片的注意事项

        1、 切片定义后不可以直接使用,需要让其引用到一个数组,或者make一个空间供切片来使用。直接使用输出[]。

        2、切片使用不可以越界。

        3、简写方式

var slice = arr[0:end]  ------>  var slice = arr[:end]

var slice = arr[start:len(arr)]  ------>  var slice = arr[start:]

var slice = arr[0:len(arr)]  ------>  var slice = arr[:]

        4、切片可以继续切片 

var intarr [6]int = [6]int{3, 6, 9, 1, 4, 7}

var slice1 []int = intarr[1:5]

Slice2 := slice[1:2]

        5、切片可以动态增长

func main() {
	var intarr [6]int = [6]int{3, 6, 9, 1, 4, 7}
	slice := intarr[1:5]
	slice[0] = 5   //原数组会改变
	fmt.Printf("长度:%v   容积:%v\n",len(slice),cap(slice))
	slice2 := append(slice,8,2)   //append指向的是一个新的数组
	fmt.Println(intarr)   //原数组没有变化
	fmt.Println("1-slice2:",slice2)
	fmt.Println("1-slice:",slice)
	//底层原理
	//1、底层追加元素的时候对数组进行扩容,老数组扩容为新数组
	//2、创建一个新数组,将老数组中的6,9,1,4复制到新数组中,再追加两个元素8,2
	//3、slice2底层数组的指向是新数组,老数组是不变的
	//4、往往我们在使用追加的时候想要做的效果是给一个slice进行追加
	slice = append(slice, 8,2)
	fmt.Println("2-slice:",slice)
	fmt.Println(intarr)    //原数组没有变化
	//5、底层的新数组还是不能维护,需要通过切片来进行间接维护操作
//6、可以通过append函数将切片追加给切片
slice3 := []int{99,44}
slice = append(slice,slice3...)   //后面的...是必须要加的
fmt.Println("3-slice:",slice)
}

        6、 切片的拷贝

a := []int{1,4,7,3,6,9}
b := make([]int,10)
//拷贝
copy(b,a)   //a里面的元素给b
fmt.Printf("a:%v     b:%v\n",a,b)

映射(Map)

映射的定义 

        Go语言中内置的一种类型,它将键值相关联,我们可以通过键key来获取值value。类似其他语言的集合。


基本语法

                            Var  map变量名  map[key_type]value_type

         1、Key、value的类型:bool,数字,string,指针,channel,还可以是只包含前面几个类型的接口、结构体、数组。

        2、Key通常int,string类型,value通常为数字(整数、浮点数)、string、map、结构体。

        3、Key部分Slice、map、function不可以

func main() {
	//定义map变量
	var a map[int]string
	//只声明map的话是没有分配内存空间的
	//必须经过make函数进行初始化,才会分配对应的内存空间
	a = make(map[int]string, 10) //map可以存放10个键值对
	//将键值对存入map中
	a[202001] = "dwe"
	a[202002] = "drb"
	a[202003] = "张三"
	//输出集合
	fmt.Println(a)
}

    多种基本语法

func main() {
	//方式1
	//定义map变量
	var a map[int]string
	//只声明map的话是没有分配内存空间的,必须经过make函数进行初始化,才会分配对应的内存空间
	a = make(map[int]string, 10) //map可以存放10个键值对

	//方式2
	b := make(map[int]string, 10)

	//方式3
	c := map[int]string {
		202201:"cdwe",
		202202:"cdrb",
		202203:"c张三",
	}
	//将键值对存入map中
	a[202001] = "adwe"
	a[202002] = "adrb"
	a[202003] = "a张三"
	b[202101] = "bdwe"
	b[202102] = "bdrb"
	b[202103] = "b张三"
	//输出集合
	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
}

特点 

        1、map集合在使用之前一定要make

        2、Map的key-value时无序的

        3、Key有唯一性,当key一样时后面的value会替换前面的value

        4、Value可以重复 

        5、make函数的第二个参数可以省略,默认分配一个内存

 相关操作

        (一)增加和更新操作

                Map[“key”] = value  ------>  如果key还没有的话就添加,如果key已经存在,就是修改。

        (二)删除操作

                delete(map,”key”)  ------>  如果key存在则删除,不存在则不进行任何操作也不会报错

                delete(b,202102)

        (三)清空操作(没有提供单独的函数直接清空)

              1、 如果我们想删除map的所有key,没有一个专门的方法一次删除,可以遍历一下                         key,逐个删除。

              2、或者map = make(),make一个新的,让原来的成为垃圾,被gc收回

        (四)查找操作

               Value,bool = map[key]

               根据key找value,还有一个bool值看存不存在这个key值。

        (五)获取长度

                len(map名)      len(b)

        (六)遍历操作

//遍历:

for k,v := range c {

fmt.Printf("key:%v  value:%v   \t",k,v)

}

加深难度

a := make(map[string]map[int]string)  //注意后面的那个map还没有make

//赋值

a["1001"] = make(map[int]string,3)

a["1001"][100101] = "张三"

a["1001"][100102] = "李四"

a["1001"][100103] = "王五"

a["1002"] = make(map[int]string,3)

a["1002"][100201] = "2张三"

a["1002"][100202] = "2李四"

a["1002"][100203] = "2王五"

//遍历

for k1,v1 := range a {

fmt.Println(k1)

for k2,v2 := range v1 {

fmt.Printf("key:%v  value:%v   \t",k2,v2)

}

fmt.Println("\n----------")

}

 若发现本文有问题,希望各位大佬在评论区点出,加深学习。

posted @ 2023-02-06 17:27  怜雨慕  阅读(313)  评论(0编辑  收藏  举报