接着切片的声明和赋值,现在索引获取切片元素。定义长度是5,元素3,赋值给nums,如下
获取元素
nums := make([]int,3,5)
获取元素使用nums[0]
开始进行获取,如下
fmt.Println(nums[0])
fmt.Println(nums[1])
fmt.Println(nums[2])
运行
[root@www.linuxea.com /opt/Golang/work2]# cat make.go
package main
import "fmt"
func main(){
nums := make([]int,3,5)
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
fmt.Println(nums[0])
fmt.Println(nums[1])
fmt.Println(nums[2])
}
如果你获取的元素超出了长度,就会抛出panic,如:
goroutine 1 [running]:
main.main()
/opt/Golang/work2/make.go:9 +0x2ab
exit status 2
4.6切片元素修改
修改第三个元素是100
nums[2] = 100
这里的索引就是2,因为从0到2是三
如下:
package main
import "fmt"
func main(){
nums := make([]int,3,5)
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
fmt.Println(nums[0])
fmt.Println(nums[1])
fmt.Println(nums[2])
nums[2] = 100
fmt.Println(nums)
}
运行
[root@www.linuxea.com /opt/Golang/work2]# go run make.go
[]int{0, 0, 0} 3 5
0
0
0
[0 0 100]
4.7切片元素添加
切片通过append进行添加,如下:
nums = append(nums,100)
append添加的时候会返回一个值,将返回值赋值到nums。
而后在打印下长度和容量
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
[root@www.linuxea.com /opt/Golang/work2]# cat make.go
package main
import "fmt"
func main(){
nums := make([]int,3,5)
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
fmt.Println(nums[0])
fmt.Println(nums[1])
fmt.Println(nums[2])
nums[2] = 100
fmt.Println(nums)
nums = append(nums,100)
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
}
运行
[root@www.linuxea.com /opt/Golang/work2]# go run make.go
[]int{0, 0, 0} 3 5
0
0
0
[0 0 100]
[]int{0, 0, 100, 100} 4 5
如上,最下面那行中,可以看到长度从之前的3,在执行append后变成4,容量还是5。
- 如果继续添加元素,容量在超过5后,容量会随着长度自动增长。增长的个数
如:
[root@www.linuxea.com /opt/Golang/work2]# cat make.go
package main
import "fmt"
func main(){
nums := make([]int,3,5)
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
fmt.Println(nums[0])
fmt.Println(nums[1])
fmt.Println(nums[2])
nums[2] = 100
fmt.Println(nums)
nums = append(nums,100)
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
nums = append(nums,100)
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
nums = append(nums,100)
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
nums = append(nums,100)
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
nums = append(nums,100)
fmt.Printf("%#v %d %dn",nums,len(nums),cap(nums))
}
运行
[root@www.linuxea.com /opt/Golang/work2]# go run make.go
[]int{0, 0, 0} 3 5
0
0
0
[0 0 100]
[]int{0, 0, 100, 100} 4 5
[]int{0, 0, 100, 100, 100} 5 5
[]int{0, 0, 100, 100, 100, 100} 6 10
[]int{0, 0, 100, 100, 100, 100, 100} 7 10
[]int{0, 0, 100, 100, 100, 100, 100, 100} 8 10
可以看到,当长度超过容量后,容量就会自动增加。增加多少取决于扩展的算法。
- 图解append扩展
数组的空间是连续的。比如说,make一个长度为3,容量为5的int切片,长度为3将会填充0,1,2索引位。
make([]int,3,5)
如下图:
go会自动申请好底层数组以供使用,当我们打印int类型的切片索引的时候,显示为0
如上图,当append追加一个元素100的时候,就会占用一个数组容量,这个过程对于底层的数组是不会变的,图中因为容量是5,而现在append后长度是4。在追加一个101,也不会变,长度和容量持平。如果继续追加102,如:
nums = append(nums,102)
此时底层数组就不够用了。这时候就会重新申请数组。而这个数组的长度也是会进行扩展,扩展是根据扩展的算法进行计算。通常是成倍增加。并且,底层数组也会指向到新的数组之上。如下:
事实上,当底层数组修改后,nums数组指针指向也会被修改指向新的地址,而后在使用nums接收,也就是赋值给nums
nums = append(nums,100)