Go语言中切片slice的声明与使用
程序员文章站
2024-01-29 17:43:58
...
一、切片slice的定义
Go语言中的切片,是一种动态数组,它是对数组的扩展。
- 与数组相⽐,切⽚的⻓度是不固定的,可以追加元素,在追加时可能使切⽚的容量增⼤。
- 切⽚本身没有任何数据,它们只是对现有数组的引⽤。
- 切⽚与数组相⽐,不需要设定⻓度,在[]中不⽤设定值,相对来说⽐较⾃由。
- 从概念上⾯来说slice像⼀个结构体,这个结构体包含了三个元素:
1)指针,指向数组中slice指定的开始位置;
2)⻓度,即slice的⻓度;
3)最⼤⻓度,也就是slice开始位置到数组的最后位置的⻓度。
二、切片的语法
2.1 声明切片
2.1.1 声明⼀个未指定⻓度的数组来定义切⽚
- var identifier []type
- 切⽚不需要说明⻓度;
- 该声明⽅式,且未初始化的切⽚为空切⽚。该切⽚默认为 nil,⻓度为 0。
2.1.2 使⽤make()函数来创建切⽚:
- var slice1 []type = make([]type, len)
- 可以简写为: slice1 := make([]type, len)
- 可以指定容量,其中capacity为可选参数: make([]T, length, capacity)
//mySlice.go
package main
import (
"fmt"
)
func main() {
//fmt.Println("Hello World!")
//1)切片
var numbers = make([]int, 3, 5)
fmt.Printf("%T\n", numbers)
fmt.Printf("len=%d cap=%d slice=%v\n", len(numbers), cap(numbers), numbers)
}
效果如下:
2.2 初始化
2.2.1 直接初始化切片
s :=[] int {1,2,3 }
2.2.2 通过数组截取来初始化切⽚
数组: arr := [5]int {1,2,3,4,5}
- 1)s := arr[:]
切⽚中包含数组所有元素 - 2)s := arr[startIndex:endIndex]
将arr中从下标startIndex到endIndex-1 下的元素创建为⼀个新的切⽚(前闭后开),⻓度为endIndex-startIndex - 3)s := arr[startIndex:]
缺省endIndex时将表示⼀直到arr的最后⼀个元素; - 4)s := arr[:endIndex]
缺省startIndex时将表示从arr的第⼀个元素开始。
2.2.3 通过切片截取来初始化切片
可以通过设置下限及上限来设置截取切⽚ [lower-bound:upper-bound]
//mySlice2.go
package main
import (
"fmt"
)
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
func main() {
//fmt.Println("Hello World!")
//1)切片
// var numbers = make([]int, 3, 5)
// fmt.Printf("%T\n", numbers)
// fmt.Printf("len=%d cap=%d slice=%v\n", len(numbers), cap(numbers), numbers)
//2)截取切片
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
printSlice(numbers)
//打印原始切片
fmt.Println("numbers== ", numbers)
//打印子切片,从索引1到索引4,左闭右开,[1,4)
fmt.Println("numbers[1:4]== ", numbers[1:4])
//默认下限为0,[0,3)
fmt.Println("numbers[:3]== ", numbers[:3])
//默认上限为len(s),[4,len(s))
fmt.Println("numbers[4:]== ", numbers[4:])
//打印子切片,[0,2)
number2 := numbers[:2]
printSlice(number2)
//打印子切片,[2,5)
number3 := numbers[2:5]
printSlice(number3)
}
效果如下:
三、切片里的len()和cap()函数
- 切⽚的⻓度是切⽚中元素的数量。
- 切⽚的容量是从创建切⽚的索引开始的底层数组中元素的数量。
- 切⽚是可索引的,并且可以由 len() ⽅法获取⻓度, 切⽚提供了计算容量的⽅法 cap(), 可以测量切⽚最⻓可以达到多少。 [数组计算cap()结果与len()相同]。
- 切⽚实际的是获取数组的某⼀部分, len切⽚<=cap切⽚<=len数组。
- cap()的结果决定了切⽚截取的注意细节。
//mySlice02.go
// mySliceCap project main.go
package main
import (
"fmt"
)
func main() {
sliceCap()
}
func sliceCap() {
arry := [...]string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"}
fmt.Println("cap(arry)= ", cap(arry), arry)
//截取数组,形成切片
sli01 := arry[2:8]
fmt.Printf("%T\n", sli01)
fmt.Println("cap(sli01)= ", cap(sli01), sli01)
sli02 := arry[4:7]
fmt.Println("cap(sli02)= ", cap(sli02), sli02)
//截取切片,形成切片
sli03 := sli01[3:9]
fmt.Println("截取sli01[3:9]后形成sli03: ", sli03)
sli04 := sli02[4:7]
fmt.Println("截取sli02[4:7]后形成sli04: ", sli04)
//切片是引用类型
sli04[0] = "x"
fmt.Print(arry, sli01, sli02, sli03, sli04)
}
运行结果如下:
四、切片是引用类型
- slice没有⾃⼰的任何数据,它只是底层数组的⼀个引⽤,对slice所做的任何修改都将反映在底层数组中。
- 数组是值类型,⽽切⽚是引用类型。
修改数组的案例,如下:
//mySlice04.go
// mySliceCmp project main.go
package main
import (
"fmt"
)
func main() {
a := [4]float64{67.7, 89.8, 21, 78}
b := []int{2, 3, 5}
fmt.Printf("变量a -- 地址: %p, 类型: %T, 数值: %v, 长度: %d\n", &a, a, a, len(a))
fmt.Printf("变量b -- 地址: %p, 类型: %T, 数值: %v, 长度: %d\n", &b, b, b, len(b))
c := a
d := b
fmt.Printf("变量c -- 地址: %p, 类型: %T, 数值: %v, 长度: %d\n", &c, c, c, len(c))
fmt.Printf("变量d -- 地址: %p, 类型: %T, 数值: %v, 长度: %d\n", &d, d, d, len(d))
a[1] = 200
fmt.Println("a= ", a, " c= ", c)
d[0] = 100
fmt.Println("b= ", b, " d= ", d)
}
运行结果如下:
- 修改切⽚数值
当多个⽚共享相同的底层数组时,每个元素所做的更改将在数组中反映出来。
修改切片里的值,案例如下:
//mySlice04.go
// mySliceChg project main.go
package main
import (
"fmt"
)
func main() {
//定义数组
arry := [3]int{1, 2, 3}
//根据数组截取切片
nums1 := arry[:]
nums2 := arry[:]
fmt.Println("arry= ", arry)
nums1[0] = 100
fmt.Println("arry= ", arry)
nums2[1] = 200
fmt.Println("arry= ", arry)
fmt.Printf("变量arry --地址: %p\n", &arry)
fmt.Printf("变量nums1 --地址: %p\n", &nums1)
fmt.Printf("变量nums2 --地址: %p\n", &nums2)
}
运行结果如下:
上一篇: .NET Core简单注入
推荐阅读
-
Go语言中切片slice的声明与使用
-
Go语言开发中redis的使用详解
-
Python语言编程学习:numpy中的array格式数据切片与pandas中的dataframe格式数据切片、相互转换
-
Go语言中切片使用的注意事项小结
-
详解Swift中对C语言接口缓存的使用以及数组与字符串转为指针类型的方法
-
详解Swift中对C语言接口缓存的使用以及数组与字符串转为指针类型的方法
-
详解Python中的__getitem__方法与slice对象的切片操作
-
详解Python中的__getitem__方法与slice对象的切片操作
-
tensorflow中tf.slice和tf.gather切片函数的使用
-
jsp中变量及方法的声明与使用