这是我参与「第三届青训营 -后端场」笔记创作活动的第3篇笔记。
一、数组
1.1、数组定义
数组的定义与创建方式:
/**
一、数组的创建方式
*/
func Test_07_01(t *testing.T) {
//1、定义
var balance [10]float32
//2、定义长度且进行初始化必须使用=
var balance1 = [11]float32{100, 20.1}
//根据元素长度来设置数组大小
numArr := []int{1, 2, 3, 4, 5}
numArr2 := [...]int{1, 2, 3, 4, 5}
//{指定位置: 指定位置值},其他都为0
numArr3 := [4]int{2: 100}
//多组指定位置值
numArr4 := [5]int{1: 100, 2: 300, 4: 500}
fmt.Println(balance)
fmt.Println(balance1)
fmt.Println(numArr)
fmt.Println(numArr2)
fmt.Println(numArr3) //[0 0 100 0]
fmt.Println(numArr4) //[0 0 100 0]
}
1.2、数组的遍历
/**
二、数组的遍历
*/
func Test_07_02(t *testing.T) {
//1、数组赋值以及遍历
var nums [10]int
for i := 0; i < len(nums); i++ {
nums[i] = i * 10 + i
fmt.Print(nums[i], " ") //0 11 22 33 44 55 66 77 88 99
}
fmt.Println()
//2、数组的长度
var nums1 = [...]int{1,2,3}
fmt.Println(len(nums1)) //3
//3、for...range遍历
for i,value := range nums1{
fmt.Print("[",i,"] = ", value, " ") //[0] = 1 [1] = 2 [2] = 3
}
}
1.3、多维数组
/**
三、多维数组
*/
func Test_07_03(t *testing.T) {
//定义二维数组
var nums = [2][3]int{
{1,2,3},
{4,5,6},
}
//遍历二维数组
for i := 0; i < len(nums); i++ {
for j := 0; j < len(nums[i]); j++ {
fmt.Print(nums[i][j], " ")
}
fmt.Println()
}
/**
1 2 3
4 5 6
*/
}
1.4、数组是值类型
Go中的数组是值类型,而不是引用类型。这意味着当它们被分配给一个新变量时,将把原始数组的副本分配给新变量。如果对新变量进行了更改,则不会在原始数组中反映。
/**
四、数组是值类型,赋值给其他是值拷贝,修改赋值的数组,原先不会改变
*/
func Test_07_04(t *testing.T) {
//测试改变赋值后的数组,原数组是否会改变?不会,因为是值类型
var nums = [3]int{1,2,3}
nums1 := nums
nums1[2] = 666
fmt.Println("nums:", nums) //nums: [1 2 3]
fmt.Println("num1:", nums1) //num1 [1 2 666]
//数组的大小不同,表明类型不同。之后切片可以来进行解决这个问题
var nums2 [5]int
//nums = nums2 //此时就会报编译错误,大小不同不能进行赋值
}
注意:数组的大小是类型的一部分。因此[5]int和[25]int是不同的类型。因此,数组不能被调整大小。不要担心这个限制,因为切片的存在是为了解决这个问题。
二、切片
2.1、初步使用
package third_ArraryAndSlice
import "fmt"
import "testing"
/**
一、切片定义与使用
切片:数组的抽象(动态数组),Go 数组的长度不可改变,在特定场景中这样的集合就不太适用。
与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大
核心:现有数组的引用。
描述数据类型:slice像一个结构体,包含三个元素
1、指针,指向数组中slice指定的开始位置
2、长度,即slice的长度
3、最大长度,也就是slice开始位置到数组的最后位置的长度
*/
func Test_08_01(t *testing.T) {
//1、创建切片。长度为5,容量为10的切片
mslice := make([]int, 5, 10)
fmt.Println(mslice,",长度为:", len(mslice), ",容量为:", cap(mslice))//[0 0 0 0 0] ,长度为: 5 ,容量为: 10
//2、拿到数组指定位置的切片
mslice2 := [5]int{1,2,3,4,5}
mslice3 := mslice2[2:4] //[2,4)区间位置
mslice4 := mslice2[:3] //[0,3)区间位置
fmt.Println(mslice3) //[3 4]
fmt.Println(mslice4) //[1 2 3]
//3、若是对切片修改,其会对原始数组也进行修改
mslice3[0] = 5
fmt.Println()
fmt.Println("切片修改:", mslice3) //切片修改: [5 4]
fmt.Println("源数组:", mslice2) //源数组: [1 2 5 4 5]
}
2.2、长度与容量
/**
二、切片的长度与容量
*/
func Test_08_02(t *testing.T) {
var nums = make([]int, 3, 5)
fmt.Printf("len=%d cap=%d slice=%v\n",len(nums),cap(nums) ,nums) //len=3 cap=5 slice=[0 0 0]
}
2.3、append()与copy()【前者返回对象时深拷贝;后者复制也是深拷贝】
/**
三、append()和copy()函数
append():append 向slice里面追加一个或者多个元素,然后返回一个和slice一样类型的slice
1、append函数会改变slice所引用的数组的内容,从而影响到引用同一数组的其它slice。
2、当slice中没有剩余空间(即(cap-len) == 0)时,此时将动态分配新的数组空间。返回的slice数组指针将指向这个空间,而原 数组的内容将保持不变;其它引用此数组的slice则不受影响
copy():copy 函数copy从源slice的src中复制元素到目标dst,并且返回复制的元素的个数
*/
func Test_08_03(t *testing.T) {
//1、append()追加返回的数组与源数组无关!!!相当于来了层【深拷贝】
var nums []int
nums1 := append(nums, 0)
printSlice(nums) //len=0,cap=0,slice=[]
printSlice(nums1) //len=1,cap=1,slice=[0]
//添加多个元素
nums1 = append(nums1, 2,3,4)
printSlice(nums) //len=0,cap=0,slice=[]
printSlice(nums1) //len=4,cap=4,slice=[0 2 3 4]
//创建当前切片的两倍长度、两倍容量。【注意:[]int,[]必须写在前面】
slices := make([]int, len(nums1), (cap(nums1)) * 2)
//2、copy()也是相当于深拷贝,复制之后两者无关
copy(nums1, slices) //将nums1中的内容拷贝到slices中(新创建的)
slices[2] = 5
println(nums1)
println(slices)
}
//定义函数
func printSlice(x []int) {
//注意其中有%d,%v,需要使用printf输出
fmt.Printf("len=%d,cap=%d,slice=%v\n",len(x), cap(x), x)
}