golang数组和切片
数组
go语言中数据属于值类型,也就是可以直接赋值操作的,还有一种类型叫做引用类型,引用类型一般是通过指针来操作。值类型有 int/uint 字符串,bool、byte、array。引用类型有指针,结构体,通道、等等。
数组的定义
func main() { var list [3]int fmt.Println(list) }
也可以定义的时候直接赋值
func main() { var list = [3]int{1, 3, 4} fmt.Println(list) }
如果定义了数组没有赋值,那么值还是元素类型的零值。
数据组的一些操作
获取数组的长度
使用len关键字可以获取数组的长度,也就是数组元素的个数。
func main() { var list = [3]int{1, 3, 4} fmt.Println(len(list)) }
获取数组的容量
使用cap关键字可以获取数组的容量,
func main() { var list = [39]int{1, 3, 4} fmt.Println(cap(list)) }
获取元素
通过下标来获取某一个元素的值。
func main() { var list = [39]int{1, 3, 4} fmt.Println(list[1]) fmt.Println(list[2]) fmt.Println(list[3]) fmt.Println(list[4]) }
修改元素
通过下标修改元素的值
func main() { var list = [39]int{1, 3, 4} list[1] = 100 }
数组的遍历
通过range来遍历数组。
func main() { var list = [39]int{1, 3, 4} //i is a index v is a value for i, v := range list { fmt.Println(i, v) } }
多维数组
多维数据定义的格式
func main() { list1 := [3][2]int{ {1, 2}, } fmt.Println(list1) }
也可以用下面方式
func main() {
var list1 [3][2]int
list1[0] = [2]int{1, 2}
fmt.Println(list1)
}
遍历多维数组
func main() { var list1 [3][2]int list1 = [3][2]int{ {1, 2}, } for _, k := range list1 { for _, j := range k { fmt.Println(j) } } }
切片 slice
切片和数组的唯一区别在于,切片的容量是可以变化的,当容量不够的时候会自动扩容,扩容的机制,是成倍扩,slice底层也是一个数组。
创建切片
类型推导方式,创建及赋值,初始化,如果没有初始化的slice是无法直接使用的
func main() { s1 := []int{1, 2} fmt.Println(s1) }
通过make函数创建,make函数第一个参数是,需要初始化的类型,支持map chan,后面两个参数一个是长度一个是容量,下面代码表示,创建一个长度为4,容量为10 的的slice返回。
func main() {
var s1 []int
s1 = make([]int, 4, 10)
fmt.Println(s1)
}
切片元素的操作
切片元素的操作和数组是一样的通过下标来操作,可以通过append来添加元素
添加元素
func main() { var s1 []int s1 = make([]int, 4, 10) s1 = append(s1, 1, 1, 1) fmt.Println(s1) }
删除元素
go语言没有提供内置的函数用来删除一个slice的元素,不过通过下标操作来删除一个元素
func main() { var s1 []int s1 = make([]int, 0) s1 = append(s1, 1, 2, 3) fmt.Println(s1) s1 = append(s1[:1], s1[1+1:]...) //切片后面跟...表示把这个切片的元素一个一个当做参数传入 fmt.Println(s1) }
范围删除
删除下标从3到5的元素
func main() { var s1 []int s1 = make([]int, 0) s1 = append(s1, 1, 2, 3, 5, 6, 8, 1) s1 = append(s1[:3], s1[6:]...) fmt.Println(s1) }
对数组切片
切片底层就是通过数组实现的,所有可以对数组切片,生成一个新的切片
func main() { var list = [5]int{1, 2, 3, 4, 5} s1 := list[1:] fmt.Println(s1) fmt.Printf("%T\n", s1) }
func main() {
var a = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
s1 := a[:5]
// &a表示当前整个数组a的内存地址,s1因为本身就是切片,内存中存储的内存地址,所以不需加&去获取地址了,这里获取的是s1中存储的地址
fmt.Printf("%p,%p\n", &a, s1) //内存地址是一样的
}
修改地址数组对切片的影响
func main() { var a = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} s1 := a[:5] a[2] = 1000 fmt.Println(s1) fmt.Println(a) a[9] = 10000 fmt.Println(a) }
修改切片对底层数组的影响
func main() { var a = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} s1 := a[:5] //把切片最后一个元素修改成100 s1[len(s1)-1] = 100 fmt.Println(s1) fmt.Println(a) }
小总结
切片底层是一个数组实现的,所以无论你是操作底层的数组,还是切片,都将改变整个数据的值,
Welcome to visit