数组与切片
定义数组
var score [5]float64
//四种初始化数组方式
var numArr01 [3]int = [3]int{1,2,3}
var numArr02 = [3]int{4,5,6}
var numArr03 = [...]int{8,9,10}
var numArr04 = [...]int{1:800, 2:900, 3:999}
//类型推导
strArr05 := [...]string{1:"tom", 0:"jack", 8:"aim"}
数组的遍历
常规遍历
略
for-range结构遍历
go语言独有的一种结构
for index, value := range arry01 {...}
第一个参数是下标,第二个是值,可用占位符_代替
都为局部变量
index和value不是固定的,可自己取名,一般这样写
数组注意事项
数组是多种数据类型的组合,一旦声明,长度固定,不能动态变化
数组中的元素可以是任意类型,包括引用类型,但是不能混用
没有赋值为默认值
数组下标必须在指定范围内使用,否则会报panic错误,数组越界
若想在其他函数中修改,可以使用引用传递(指针方式)
长度是数组的一部分,传递时需考虑长度,所以不能:arr[4]=arr[3],也不能:arr[]=arr[3]
切片介绍
引用类型,遵循引用类型传递机制
动态变化的数组
访问遍历和求长度都和数组一样
定义
var 切片名 []类型
var a []int
基本使用
var intArr [5]int =[...]int{1,2,3,4,5,6}
slice := intArr[1:3] //包含左不包含右
len(slice):求切片的长度:2
cap(slice):求切片的容量:5,可变
切片分析
底层来说切片是一个数据结构(struct结构体)
type slice struct {
ptr *[2]int
len int
cap int
}
切片的使用
方式1:定义一个切片然后让切片去引用一个创建好的数组
方式2:通过make来创建切片
var 切片名 []type = make([]type , len, [cap])
var slice []float64 = make([]float64,5,10)
slice[1] = 10
若不赋值使用默认值
cap可选,若分配了cap则要大于等于len
通过make方法创建的对应数组是由make底层维护,对外不可见,即只能通过slice去访问各个元素
方式3:定义一个切片,就指定具体数组,使用原理与make的方式
var strSlice []string = []string{"tom","jack","mary"}
方式一与方式二的区别
方式一是直接引用数组,数组实现存在程序员可见
方式二通过make创建切片也会创建一个数组,由切片在底层维护程序员看不见
切片的遍历
f常规遍历
for-range遍历
for i, v := range slice {...}
切片使用细节
初始化:var slice = arr[startIndex:endIndex](不含endIndex)
初始化不能越界,范围在0-len之间,但可动态增长
简写
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[:len(arr)]
cap是一个内置函数,用于统计切片的容量
切片定义后,还不能使用,因为本身是一个空,虚引用一个数组,或make一个空间切片来使用
切片可以继续切片
slice := slice[1:2]
append内置函数可以对切片进行动态追加
slice3 := append(slice3,400,500,600)
append操作本质就是对数组扩容
go 底层会创建一下新的数组 newArr(安装扩容后大小)
将 slice 原来包含的元素拷贝到新的数组 newArr
slice 重新引用到 newArr
注意 newArr 是在底层来维护的,程序员不可见
切片的拷贝操作
copy(slice4,slice5)
4往5里拷贝,参数数据类型为切片,切空间相互独立
4的长度可以大于5,进行截取操作(即不显示玩)
引用类型,尊寻引用类型传递机制
var slice2 = slice
slice2[0] = 10
执行后slice的第一个元素也会变为10
函数传递地址传递
string和slice
string是一个byte数组,string也可以进行切片处理
str := "hello@ygh"
slice = str[2:]
fmt.println("slice=",slice)
string不可变,因此不能通过str[0]来修改字符串
若要修改:可以先将 string -> []byte / 或者 []rune -> 修改 -> 重写转成 string
arr1 := []byte(str)
arr1[0] = 'z'
arr1 := []rune(str)
arr1[0] = '北'
str = string(arr1)
练习
切片存放指定数量的菲波那切数列
一切在函数实现因为切片为引用类型,在函数里创建切片,在main函数;里也能用
package main
import (
"fmt"
)
func fbn(n int) ([]uint64) {
//声明一个切片,切片大小 n
fbnSlice := make([]uint64, n)
//第一个数和第二个数的斐波那契 为1
fbnSlice[0] = 1
fbnSlice[1] = 1
//进行for循环来存放斐波那契的数列
for i := 2; i < n; i++ {
fbnSlice[i] = fbnSlice[i - 1] + fbnSlice[i - 2]
}
return fbnSlice
}
func main() {
/*
1)可以接收一个 n int
2)能够将斐波那契的数列放到切片中
3)提示, 斐波那契的数列形式:
arr[0] = 1; arr[1] = 1; arr[2]=2; arr[3] = 3; arr[4]=5; arr[5]=8
思路
1. 声明一个函数 fbn(n int) ([]uint64)
2. 编程fbn(n int) 进行for循环来存放斐波那契的数列 0 =》 1 1 =》 1
*/
//测试一把看看是否好用
fnbSlice := fbn(20)
fmt.Println("fnbSlice=", fnbSlice)
}