August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
Go语言基础-切片(Slice)
发布:2021年01月18日 | 作者:augustrush | 阅读量: 1166

切片,用于表示多个数据(数据集合),可以理解为动态数组

切片是go语言中重要的数据类型,每个切片对象内部都维护着:数据指针,切片长度、切片容量。

type slice struct {
    array unsafe.Pointer
    len int
    cap int
}

在向切片中追加的数据个数大于容量时,内部会自动扩容且每次扩容都是当前容量的2倍,如果当前容量大于1024时那么每次扩容则只增加当前容量的1/4。


1.1 创建切片

// 方式一
var num = []int

// 方式二
var data = []int {11, 22, 33}
// data := []int {11, 22, 33}    //简写

// 方式三
// make 只能用于:切片、字典、channel
// 三个参数分别是:1.类型  2.长度  3.容量
var users = make([]string, 1, 3) // 声明一个容量为3的切片,初始化1个默认string类型的值       

// 默认创建长度为0 容量为0的切片 并开辟一块内存空间让指针指向该切片
var v1 = new([]int)

var v2 *[]int // 默认开辟一块内存空间并指向nil


1.2自动扩容

var v1 = make([]int, 1, 3) // 如下图,生成一个长度为1,容量为3的切片
fmt.Println(len(num), cap(num))
// 输出的结果为: 1 3

data := make([]int, 3) // 如果只有2个参数,那么它代表 生成一个长度为3,容量为3的切片
fmt.Println(len(data), cap(data))
// 输出的结果为: 3 3

v1 := make([]int, 3)

v2 := append(v1, 66)

append返回一个切片,v1,v2指向同一块内存地址。只是长度发生改变

v1[0] = 99

fmt.Println(v1)
fmt.Println(v2)

/* 
输出的结果为:
        [99]
        [99 66]
*/

引发自动扩容时:

v1 := []int {11, 22, 33}

v2 := append(v1, 44)

当引发自动扩容时,v1和v2就不是指向同一块内存地址。append返回的是一个新开辟内存地址的切片。修改v1的值的时候,v2的值就不会修改

v1[0] = 0

/*
输出的结果为:
    [0 22 33]
    [11 22 33 44]
*/


1.3 常见操作


1.3.1 长度和容量

可以通过内置函数len()cap()来获取切片的长度和容量

var v1 = make([]int, 1, 3) 
fmt.Println(len(num), cap(num))


1.3.2 索引

通过索引获取对应值

info := []string {"august rush", "china", "18"}

info[0]
info[1]
info[2]

如果通过make创建的切片需要注意:

info := make([]string, 2, 5)

info[0]
info[1]
info[2] // 编译报错,因为切片的长度为2,不能以容量来判断

通过索引修改对应值

info[0] = "Thrump is a trouble"


1.3.3 切片

v1 := []int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

v2 := v1[1:3]  // 取 从下标为n开始到下标至m-1之间的值

v3 := v1[:3]   // 取 从下标0开始到下标m-1之间的值

v4 := v1[3:]   // 去 从下标n开始至集合末尾的之间的值

切片出来的数值与原数值内存指向同一块空间

v := []int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

v1 := v[1:5]
v2 := v[:5]
v3 := v[4:]

fmt.Println(v1, v2, v3)
// 输出的结果为:[1 2 3 4] [0 1 2 3 4] [4 5 6 7 8 9]

v[4] = 444

fmt.Println(v, v1, v2, v3)
// 输出的结果为:[0 1 2 3 444 5 6 7 8 9] [1 2 3 444] [0 1 2 3 444] [444 5 6 7 8 9]


1.3.4 追加

使用内置函数append()

v := []int {0, 1, 2}

// 方式一:追加一个元素
v1 := append(v, 3)
fmt.Println(v1)
// 输出的结果为:[0 1 2 3]

// 方式二:连续追加多个元素
v2 := append(v, 3, 4, 5, 6)
fmt.Println(v2)
// 输出的结果为:[0 1 2 3 4 5 6]

// 方式三:追加一个切片(需要对新增的切片进行解压操作(...) )
v3 := append(v, []int {8, 9 , 10}...)
fmt.Println(v3)
// 输出的结果为:[0 1 2 8 9 10]


1.3.5 删除

Go没有内置函数进行删除操作,但可通过append()函数构造一个删除方法

v := []int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

positionIndex := 3

result := append(v[:positionIndex], v[positionIndex+1:]...)

fmt.Println(result)

// 输出的结果为:[0 1 2 4 5 6 7 8 9]

此方式有个坑:

因为append函数返回的切片与原切片指向同一块内存空间,索引原切片数据也收到影响,需要注意一下。

v := []int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

positionIndex := 3

result := append(v[:positionIndex], v[positionIndex+1:]...)

fmt.Println(v)
fmt.Println(result)

/*
输出的结果为:
    [0 1 2 4 5 6 7 8 9 9]
    [0 1 2 4 5 6 7 8 9]
*/


1.3.6 插入

Go没有内置函数进行插入操作,但可通过append()函数构造一个插入方法

v := []int {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

insertIndex := 3

// 先声明一个新切片,新切片容量+1 以防止需要扩容
new_v := make([]int, 0, len(v) + 1)

new_v = append(new_v, v[:insertIndex]...)
new_v = append(new_v, 99)
new_v = append(new_v, v[insertIndex:]...)

fmt.Println(v)
fmt.Println(new_v)

/*
输出的结果为:
        [0 1 2 3 4 5 6 7 8 9]
        [0 1 2 99 3 4 5 6 7 8 9]
*/


1.3.7 循环

方式一

for i:=0;i<len(v);i++ {
  fmt.Println(i , v[i])
}

方式二

for index, item := range v {
        fmt.Println(index, item)
}


1.4 切片嵌套


创建嵌套切片

方式一:

var v [][]int  
// 输出的结果为:[]

方式二:

var v = [][]int {[]int {1,2}, []int {3, 4}, []int {5, 6}}
// 输出的结果为: [[1 2] [3 4] [5 6]]

v1 := [][2]int {[2]int {1,2}, [2]int{3,4}}


取值

var v = [][]int {[]int {1,2}, []int {3, 4}, []int {5, 6}}
v1 := [][2]int {[2]int {1,2}, [2]int{3,4}}

fmt.Println(v)
fmt.Println(v1)

v[0] = []int {11, 22}
v[1][1] = 222
v1[1][1] = 44

fmt.Println(v)
fmt.Println(v1)

/*
输出的结果为:
        [[1 2] [3 4] [5 6]]
        [[1 2] [3 4]]
        [[11 22] [3 222] [5 6]]
        [[1 2] [3 44]]
*/


  • 标签云

  • 支付宝扫码支持一下

  • 微信扫码支持一下



基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed