谈一谈Go的切片Slice的使用方法

Slice切片本身并不是数组,它指向底层的数组 作为变长数组的替代方案,可以关联底层数组的局部或全部 为引用类型 可以直接创建或从底层数组获取生成 使用len()获取元素个数,cap()获取容量 一般使用make()创建 如果多个slice指向相同底层数组,其中一个的值改变会影响全部 make([]T, len, cap) 其中cap可以省略,则和len的值相同 len表示存数的元素个数,cap表示容量。

package main

import "fmt"

func main() {
var s1 []int //中括号里没有数字或3个点,即表示切片,而不是数组
fmt.Println(s1)
}

输出:

[]

package main

import "fmt"
import "strconv"

func main() {
a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println(a)
s1 := a[9] //取第10个元素,因为没赋值,默认为0
s2 := a[5:10] //取后5个元素(即第6个到第10个),注意起始位有包含,截止位没包含
s3 := a[5:len(a)] //取后5个元素(即第6个到第10个),注意起始位有包含,截止位没包含
s4 := a[5:] //取后5个元素(即第6个到第10个),注意起始位有包含,截止位没包含
s5 := a[:5] //取前5个元素,注意起始位有包含,截止位没包含
fmt.Println("取第10个元素(因为没赋值,默认为0):" + strconv.Itoa(s1))
fmt.Println(s2)
fmt.Println(s3)
fmt.Println(s4)
fmt.Println(s5)
}
  [1 2 3 4 5 6 7 8 9 0]
  取第10个元素(因为没赋值,默认为0):0
  [6 7 8 9 0]
  [6 7 8 9 0]
  [6 7 8 9 0]
  [1 2 3 4 5]

package main

import "fmt"

func main() {
//make([]T, len, cap)创建切片 其中cap可以省略,则和len的值相同 len表示已存放的元素个数,cap表示容量,即最多可以存放的元素个数
s1 := make([]int, 3)
fmt.Println(s1)
fmt.Println(len(s1))
fmt.Println(cap(s1))
}

输出:

  [0 0 0]
  3
  3

package main

import "fmt"

func main() {
s1 := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}
fmt.Println(s1)
fmt.Println(s1[2:])
fmt.Println(string(s1[2:4]))
fmt.Println("加上string()后输出字符串,而不是输出ASCII码:" + string(s1[2]))
}

输出:

  [97 98 99 100 101 102 103 104 105 106 107]
  [99 100 101 102 103 104 105 106 107]
  cd
  加上string()后输出字符串,而不是输出ASCII码:c


package main

import "fmt"

func main() {
s1 := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}
sa := string(s1[2:5])
sb := string(sa[1:3]) //Reslice时索引以被slice的切片为准
// sb := string(sa[1:4]) //索引不可以超过被slice的切片的容量cap()值 索引越界不会导致底层数组的重新分配而是引发错误
fmt.Println(sa)
fmt.Println(sb)
}

输出;

  cde
  de

append函数的使用

package main

import "fmt"

func main() {
s1 := make([]int, 3, 6)
fmt.Printf("%p\n", s1) //打印内存地址
s1 = append(s1, 1, 2, 3)
fmt.Printf("%v %p\n", s1, s1) //打印内存地址
s2 := append(s1, 1, 2, 3) //当添加元素超出最大的容量时,重新分配内存地址,把数据拷贝过去以后,再追加元素,则切片的地址就会发生变化了
fmt.Printf("%v %p\n", s2, s2) //打印内存地址,此时的地址与前面的不同
}


输出:

  0xc042064030
  [0 0 0 1 2 3] 0xc042064030
  [0 0 0 1 2 3 1 2 3] 0xc04203a0c0


package main

import "fmt"

func main() {
a := []int{1, 2, 3, 4, 5}
s1 := a[2:5]
s2 := a[1:3]
fmt.Println(s1) //3是s1和s2共同的部分,也就是说他们有指向相同的地址
fmt.Println(s2)
s2 = append(s2, 11, 12, 13, 1, 3, 4, 5, 6, 6, 7) //当append的时候,元素个数超出容量时,此时切片就会指向新的底层数组,而不再指向原来的数组a,而s1还是指向数组a,所以s1怎么变就不会影响s2了,这也是使用append时要注意的地方
s1[0] = 22 //当某一个切片对相同的地址的值改变时,则另外切片对应的值也会相应改变
fmt.Println(s1)
fmt.Println(s2)
}

输出:

  [3 4 5]
  [2 3]
  [22 4 5]
  [2 3 11 12 13 1 3 4 5 6 6 7]

copy函数的使用(以短的切片为参照物)

长切片拷贝到短切片

package main

import "fmt"

func main() {
s1 := []int{1, 2, 3, 4, 5}
s2 := []int{11, 12, 13, 14, 15, 16, 17, 18, 19}
copy(s1, s2)
fmt.Println(s1)
fmt.Println(s2)


输出:

[11 12 13 14 15]
[11 12 13 14 15 16 17 18 19]

短切片拷贝到长切片
package main

import "fmt"

func main() {
s1 := []int{1, 2, 3, 4, 5}
s2 := []int{11, 12, 13, 14, 15, 16, 17, 18, 19}
copy(s2, s1)
fmt.Println(s2)
fmt.Println(s1)
}

输出:
  [1 2 3 4 5 16 17 18 19]
  [1 2 3 4 5]

如何把一个切片转换给另外一个切片?
package main

import "fmt"

func main() {
s1 := []int{1, 2, 3, 4, 5}
// s2 := s1[:]
// s2 := s1
s2 := s1[:len(s1)]
fmt.Println(s2)
}


输出:
  [1 2 3 4 5]



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值