Go语言基础之切片

切片

切片是一个拥有相同类型元素的可变长度的序列。他是基于数组类型做的一层封装。支持自动扩容。

切片是一个引用类型,他内部保护地址、长度和容量。其中容量必须要比长度大。

 

切片定义

var name[]T

// 例子
var a[]string
var b[]int{}    //声明并初始化
var c[]bool{false,true}

// 其中a==nil  b和c都!=nil

 

切片的长度和容量

切片用于自己的长度和容量,使用len()求长度,使用cap()求容量

 

基于数组定义切片

func main(){
    a := [5]int{1,2,3,4,5}
    b := a[1:4]    // 基于数组创建切片,包含2,3,4
    c := a[1:]     // 2,3,4,5
    d := a[:4]     // 1,2,3
    e := a[:]      // 1,2,3,4,5
}

 

切片再切片

func main() {
	//切片再切片
	a := [...]string{"北京", "上海", "广州", "深圳", "成都", "重庆"}
	fmt.Printf("a:%v type:%T len:%d  cap:%d\n", a, a, len(a), cap(a))
	b := a[1:3]
	fmt.Printf("b:%v type:%T len:%d  cap:%d\n", b, b, len(b), cap(b))
	c := b[1:5]
	fmt.Printf("c:%v type:%T len:%d  cap:%d\n", c, c, len(c), cap(c))
}

// 切片本身是没有数据的,是对底层数组的一个视图。不能切过数组的长度。

新切片长度和容量计算公式为:底层数组容量为k的切片slice[i:j]来说,其长度为:j-i  容量为:k-i

 

使用make()函数构造切片

make([]T,size,cap)

a := make([]int,2,10)    // 创建一个长度为2,容量为10,类型为int的切片

 

切片的本质

对底层数组的封装,包含三个信息:

  • 地址(切片中第一个元素指向的内存空间);
  • 大小(切片中目前的元素个数);
  • 容量(底层数组最大存放元素的个数)。

 

切片不能直接比较

切片不能使用==来判断两个切片是否有全部相等的元素。当一个切片没有底层数组时为nil,一个nil的长度和容量都为0。但不能说一个长度和容量为0的是nil。如果要判断一个切片是否为空,使用len(s)==0来判断,不能使用s==nil判断

var s1[]int                    //len(s1)=0;cap(s1)=0;s1==nil
s2 := []int{}                  //len(s2)=0;cap(s2)=0;s1!=nil
s3 := make([]int,0)            //len(s3)=0;cap(s3)=0;s1!=nil

 

切片的赋值拷贝

func main(){
    s1 := make([]int,3)
    s2 = s1
    s2[0] = 100
    fmt.Println(s1)    // [100 0 0]
    fmt.Println(s2)    // [100 0 0]
}

 

切片遍历

func main() {
	a := []string{"北京", "上海", "广州", "深圳", "成都", "重庆"}
	for i:=0;i<len(a);i++{
		fmt.Println(a[i])
	}

	for index,value := range a{
		fmt.Println(index,value)
	}
}

 

append()方法添加元素

Go语言的内建函数append()可以为切片动态添加元素。 每个切片会指向一个底层数组,这个数组能容纳一定数量的元素。当底层数组不能容纳新增的元素时,切片就会自动按照一定的策略进行“扩容”,此时该切片指向的底层数组就会更换。“扩容”操作往往发生在append()函数调用时。

func main() {
	var numSlice []int
	for i := 0; i < 10; i++ {
		numSlice = append(numSlice, i)
	}
	fmt.Println(numSlice)
}
var citySlice []string
// 追加一个元素
citySlice = append(citySlice, "北京")
// 追加多个元素
citySlice = append(citySlice, "上海", "广州", "深圳")
// 追加切片
a := []string{"成都", "重庆"}
citySlice = append(citySlice, a...)            // 追加切片后边要加...
fmt.Println(citySlice) //[北京 上海 广州 深圳 成都 重庆]

注意:当append在原数组上还有空位时,则一同修改原数组值;如果超过原数组长度则创建新的底层数组。

slice := []int{10, 20, 30, 40, 50}
newSlice := slice[1:3]
newSlice = append(newSlice, 60)
fmt.Println(slice, newSlice)

slice1 := []int{10, 20, 30, 40}
newSlice1 := append(slice1, 50)
fmt.Println(slice1,newSlice1)

 

append()防止底层数组共享方法

func main(){
	source := []string{"Apple", "Orange", "Plum", "Banana", "Grape"}
	slice := source[2:3:3]
	fmt.Printf("slice:%v len:%d cap%d\n",slice,len(slice),cap(slice))
	slice = append(slice, "pear")
	fmt.Printf("slice:%v len:%d cap:%d\n", slice, len(slice), cap(slice))
	fmt.Println(source)
}

 

使用copy()函数复制切片

由于切片是引用类型,所以当我们复制切片的时候使用copy()来操作,如果单纯的a:=b会在修改切片a时使b也修改。

copy(destSlice,srcSlice []T)    // srcSlice:数据来源切片  destSlice:目标切片

func main(){
    a := []int{1,2,3,4,5}
    c := make([]int,5,5)
    copy(c, a)
    c[0] = 100
    fmt.Println(a)    // 1 2 3 4 5
    fmt.Println(b)    // 100 2 3 4 5
}

 

从切片中删除元素

Go语言中没有删除切片元素的方法,所以我们使用切片特性来进行操作 a = append(a[:index],a[index+1,]...)

func main(){
    a := []int{1,2,3,4,5}
    // 删除索引为2的元素
    a = append(a[:2],a[3:]...)
    fmt.Println(a)    // 1 2 4 5
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值