linuxea:go切片元素的获取修改和添加(22)


接着切片的声明和赋值,现在索引获取切片元素。定义长度是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 %d\n",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 %d\n",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 %d\n",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 %d\n",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 %d\n",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 %d\n",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 %d\n",nums,len(nums),cap(nums))
    nums = append(nums,100)
    fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums))
    nums = append(nums,100)
    fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums))
    nums = append(nums,100)
    fmt.Printf("%#v %d %d\n",nums,len(nums),cap(nums))
    nums = append(nums,100)
    fmt.Printf("%#v %d %d\n",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)
0 分享

您可以选择一种方式赞助本站

支付宝扫码赞助

支付宝扫码赞助

日期: 2019-11-23分类: Golang

标签: Golang

发表评论