数组
- 数组是具有唯一类型的一组已编号且长度固定的数据项序列
- 如果想让数组元素类型为任意类型的话,可以使用空接口作为类型
- go语言中的数组是一种值类型(不像C/C++中是指向首元素的指针),所以可以通过new() 来创建
var arr=new([5]int)
数组定义的三种方式
- var arrAge = [5]int{18, 20, 15, 22, 16}
[10]int{1,2,3}:这是一个有10个元素的,除了前三个其他元素都是0 - var arrLazy = […]int{5, 6, 7, 8, 22}
…同样可以忽略,从技术上说它们其实变化成了切片
切片和数组在声明时,最大的区别就是:数组需要长度(用…省略也是数组),而[]里面是空的则是切片 - var arrKeyValue = [5]string{3: “Chris”, 4: “Ron”}
下标为3和4的被赋了值
将数组传递给函数会消耗很多内存,有俩中方法可以避免这种现象:
- 传递数组的指针
- 使用数组的切片
var arr1 = new([5]int)
和var arr1 [5]int
的区别:
arr1的类型是*[5]int,而arr2的类型是[5]int
* 和 & 符号的讲解:
* 是一个指针变量 ,在一个类型前声明就是该类型的指针,在一个变量前声明就是取值
&是取址符 在变量前声明,会返回变量的地址
当一个指针被定义没有分配任何变量时,它的值是nil
切片
- 切片是对数组一个连续片段的引用,所以切片是一个引用类型
- 切片类似与C/C++中的数组类型,或者Python中的list类型
- 和数组不同的是,切片的长度可以在运行时修改,最小为0最大为相关数组的长度
- 切片是一个长度可变的数组
切片的初始化格式:var slice1 []type = arr1[start: end]
(左闭有开)
切片在内存中的组织方式实际上是一个有3个域的结构体:指向相关数组的指针,切片长度以及切片容量
切片的长度就是从切片的首到切片的尾的长度
切片的容量就是从切片的首到数组的尾的长度cap()
一个切片s可以扩展到它的大小上限:s=s[:cap(s)]
切片可以被重新分片,但是只能获取到start后面的元素(包括end后面数组长度前面),但是不能获取到start前面的元素
用make()创建一个切片
当相关数组还没有定义时,我们可以使用make()函数来创建一个切片同时创建好相关数组:var slice1 []type = make([]type,len)
如:slice1 := make([]int,10),那么cap(s2)==len(s2)==10
slice1:=make([]T,len,cap)(cap是可选参数)
new()和make()的区别
-
func new(Type) *Type
-
func make(Type, size IntegerType) Type
-
new(T)为每个新的类型T分配一片内存,初始化为0并且返回类型为*T的内存地址;这种方式返回一个指向类型为T,值为0的地址的指针,它适用于值类型如数组和结构体;它相当于
&T{}
-
make(T)返回一个类型为T的初始值,它只适用于3中内建的引用类型:切片,map和channel
-
不特殊声明,go默认按值传递,即传递的参数的值的副本,但是make()返回的值通过传参可以进行修改
-
很少使用new
多维切片
- 通过分片的分片,长度可以任意动态改变,go语言中多维切片可以任意切分
- 内层的切片必须单独分配(通过make函数)
bytes包 这个之后再看
For-range 结构
- 第一个返回值是 数组或者切片的索引 (可以用来改变值)
- 第二个返回值 是索引位置的值的一个拷贝,不能用来改变该索引位置的值
for ix, value := range slice1 {
...
}
// 只需要索引,可以忽略第二个值
for ix := range seasons {
fmt.Printf("%d", ix)
}
// Output: 0 1 2 3
切片重组
slice1 = slice1[0:end]
,其中end是新的末尾索引(即长度)
s1 = s1[0:len(s1)+1]
切片的复制和追加(没啥东西就没看)
切片
你将切片传递给函数时,实际上传递的是一个包含指向底层数组的指针、长度和容量的结构体的副本。这意味着如果你在函数中修改切片的元素,这些修改会反映在原始切片上。然而,如果你修改切片本身(例如,通过 append 增加元素),这些修改不会反映在原始切片上,因为你修改的是副本,而不是原始切片。
为了更清楚地说明这一点,让我们看看两种情况:
- 直接修改切片的元素
package main
import "fmt"
func modifyElements(nums []int) {
for i := range nums {
nums[i] += 1
}
}
func main() {
nums := []int{1, 2, 3}
modifyElements(nums)
fmt.Println(nums) // [2, 3, 4]
}
- 修改切片本身
package main
import "fmt"
func modifySlice(nums []int) {
nums = append(nums, 4)
fmt.Println("Inside function:", nums) // [1, 2, 3, 4]
}
func main() {
nums := []int{1, 2, 3}
modifySlice(nums)
fmt.Println("Outside function:", nums) // [1, 2, 3]
}
- 使用切片的指针修改可以起到在其它函数中添加元素的效果