首页 > 其他分享 >golang 切片

golang 切片

时间:2023-02-23 17:02:30浏览次数:28  
标签:slice4 切片 slice1 slice2 slice3 fmt golang

1.切片的定义

切片(slice)是对数组一个连续片段的引用,所以切片是一个引用类型。
切片的使用与数组类似,遍历,访问切片元素等都一样。切片是长度是可以变化的,因此切片可以看做是一个动态数组。

  • 一个切片由三个部分构成:底层数组的指针、长度(len)和容量(cap),指针指向该切片自己第一个元素对应的底层数组元素的内存地址,容量可以容纳最多元素的个数,默认为2*len。
  • cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array),其中array是slice引用的数组。

2.切片初始化

2.1 定义一个切片,然后让切片去引用一个已经创建好的数组。

package main

import "fmt"

func main() {
	var arr1 = [8]int{0, 1, 2, 3, 4, 5, 6, 7} //定义数组arr1,长度为8
	var slice []int = arr1[0:4]               //可以简写为slice := arr1[0:4]
	slice1 := arr1[0:4]                       //从0下标开始,到4下标结束,不包含下标为4的值。
	slice2 := arr1[:5]                        //从开头开始(0下标),到下标为5结束,不包含下标为5的值。
	slice3 := arr1[6:]                        //从6下标开始,到数组末尾结束。
	slice4 := arr1[:]                         //获取全部数组。
	fmt.Printf("slice的值为:%v,slice的长度为:%v,slice容量为:%v\n", slice, len(slice), cap(slice))
	fmt.Printf("slice1的值为:%v,slice1的长度为:%v,slice1容量为:%v\n", slice1, len(slice1), cap(slice1))
	fmt.Printf("slice2的值为:%v,slice2的长度为:%v,slice2容量为:%v\n", slice2, len(slice2), cap(slice2))
	fmt.Printf("slice3的值为:%v,slice3的长度为:%v,slice3容量为:%v\n", slice3, len(slice3), cap(slice3))
	fmt.Printf("slice4的值为:%v,slice4的长度为:%v,slice4容量为:%v\n", slice4, len(slice4), cap(slice4))
}

执行结果

slice的值为:[0 1 2 3],slice的长度为:4,slice容量为:8
slice1的值为:[0 1 2 3],slice1的长度为:4,slice1容量为:8        
slice2的值为:[0 1 2 3 4],slice2的长度为:5,slice2容量为:8      
slice3的值为:[6 7],slice3的长度为:2,slice3容量为:2            
slice4的值为:[0 1 2 3 4 5 6 7],slice4的长度为:8,slice4容量为:8

2.2 定一个切片,直接就指定具体数组

package main

import "fmt"

func main() {
	a := []int{}        //空切片,和nil不相等,一般用来表示一个空的集。
	b := []int{0, 1, 2} //有3个元素的切片。
	fmt.Printf("a的值为:%v,a的长度为:%v,a容量为:%v\n", a, len(a), cap(a))
	fmt.Printf("b的值为:%v,b的长度为:%v,b容量为:%v\n", b, len(b), cap(b))
}

执行结果

a的值为:[],a的长度为:0,a容量为:0
b的值为:[0 1 2],b的长度为:3,b容量为:3

2.3. make创建切片

基本语法: var切片名[]type = make([]type, len, cap) //[]type为切片类型,len为切片长度,cap为切片容量

package main

import "fmt"

func main() {
	slice1 := make([]int, 5, 10) //定义长度为5,容量为10的切片,没有赋值,所以切片的值都为int类型的默认值0
	fmt.Printf("slice的值为:%v,slice的长度为:%v,slice容量为:%v\n", slice1, len(slice1), cap(slice1))
	slice1[3] = 10 //给slice切片下标为3,赋值为10.
	fmt.Printf("slice的值为:%v\n", slice1)
	slice2 := make([]string, 4) //不指定容量,默认容量跟长度一致
	fmt.Printf("slice2的值为:%v,slice2的长度为:%v,slice2容量为:%v\n", slice2, len(slice2), cap(slice2))
}

执行结果

slice的值为:[0 0 0 0 0],slice的长度为:5,slice容量为:10
slice的值为:[0 0 0 10 0]                          
slice2的值为:[   ],slice2的长度为:4,slice2容量为:4

3. 切片的遍历

3.1 for循环遍历

package main

import "fmt"

func main() {
	var slice1 = []int{1, 2, 3, 4, 5}
	for i := 0; i < len(slice1); i++ {
		fmt.Printf("下标为%v的值为:%v\n", i, slice1[i])
	}
}

执行结果

下标为0的值为:1
下标为1的值为:2
下标为2的值为:3
下标为3的值为:4
下标为4的值为:5

3.2 for range遍历

package main

import "fmt"

func main() {
	var slice1 = []int{1, 2, 3, 4, 5}
	for k1, v1 := range slice1 {
		fmt.Printf("下标为%v的值为:%v\n", k1, v1)
	}
}

执行结果

下标为0的值为:1
下标为1的值为:2
下标为2的值为:3
下标为3的值为:4
下标为4的值为:5

4.切片的内存

切片下标为0的内存地址,对应底层数组的开始位置的内存地址,当修改切片的值时,因为切片的内存地址和数组中截取的数据内存地址相同,数组的值也会修改。

package main

import "fmt"

func main() {
	var arr1 = [8]int{1, 2, 3, 4, 5, 6, 7, 8}
	var slice1 = arr1[1:4] //取arr1数组下标为1,2,3的,[2,3,4]
	fmt.Printf("arr1的值为:%v,arr1的内存地址为:%p\n", arr1, &arr1[1])
	fmt.Printf("slice1的值为:%v,slice1的内存地址为:%p\n", slice1, &slice1[0])
	slice1[0] = 10
	fmt.Printf("修改后arr1的值为:%v\n", arr1)
	fmt.Printf("修改后slice1的值为:%v\n", slice1)
}

执行结果

arr1的值为:[1 2 3 4 5 6 7 8],arr1的内存地址为:0xc00001a308
slice1的值为:[2 3 4],slice1的内存地址为:0xc00001a308
修改后arr1的值为:[1 10 3 4 5 6 7 8]                 
修改后slice1的值为:[10 3 4] 

5. append方法

image

package main

import "fmt"

func main() {
	slice1 := []int{1, 2, 3, 4, 5, 6, 7, 8}
	fmt.Printf("slice1切片的值为:%v,slice1的长度为%v,slice1的容量为:%v\n", slice1, len(slice1), cap(slice1))
	slice1 = append(slice1, 9) //在切片slice1后面添加一个元素9
	fmt.Printf("slice1切片的值为:%v,slice1的长度为%v,slice1的容量为:%v\n", slice1, len(slice1), cap(slice1))
	slice1 = append(slice1, 10, 11, 12) //在切片slice1后面添加三个元素,10,11,12
	fmt.Printf("slice1切片的值为:%v,slice1的长度为%v,slice1的容量为:%v\n", slice1, len(slice1), cap(slice1))
	slice2 := [][]int{[]int{1, 2, 3}} //定义slice2,里面的数据类型为切片
	fmt.Printf("slice2切片的值为:%v,slice2的长度为%v,slice2的容量为:%v\n", slice2, len(slice2), cap(slice2))
	slice2 = append(slice2, slice1) //将slice1切片追加到slice2里面
	fmt.Printf("slice2切片的值为:%v,slice2的长度为%v,slice2的容量为:%v\n", slice2, len(slice2), cap(slice2))
}

执行结果

slice1切片的值为:[1 2 3 4 5 6 7 8],slice1的长度为8,slice1的容量为:8
slice1切片的值为:[1 2 3 4 5 6 7 8 9],slice1的长度为9,slice1的容量为:16                  
slice1切片的值为:[1 2 3 4 5 6 7 8 9 10 11 12],slice1的长度为12,slice1的容量为:16        
slice2切片的值为:[[1 2 3]],slice2的长度为1,slice2的容量为:1                             
slice2切片的值为:[[1 2 3] [1 2 3 4 5 6 7 8 9 10 11 12]],slice2的长度为2,slice2的容量为:2

6. copy方法

image

package main

import "fmt"

func main() {
	slice1 := []int{1, 2, 3, 4, 5, 6, 7, 8}
	fmt.Printf("slice1切片的值为:%v\n", slice1)
	slice2 := []int{9, 10}
	fmt.Printf("slice2切片的值为:%v\n", slice2)
	//内置函数copy将切片slice2中的值拷贝到slice1中将slice1中的前len(slice2)个的元素值覆盖掉。
	//slice1和slice1的数据空间是相互隔离的,互不影响。若将slice1[1]设置为2,则slice2[1]仍为10而不随着若将slice1[1]的改变而改变。
	copy(slice1, slice2) //将slice2元素copy到slice1
	fmt.Printf("slice1切片的值为:%v\n", slice1)

	//注意:由于切片是引用类型,所以slice3和slice4其实都指向了同一块内存地址。
	//修改slice4的同时slice3的值也会发生变化。
	slice3 := []int{1, 2, 3}
	slice4 := slice3
	fmt.Printf("slice3切片的值为:%v,slice3[0]的内存地址为:%p,slice3[1]的内存地址为:%p,slice3[2]的内存地址为:%p,\n", slice3, &slice3[0], &slice3[1], &slice3[2])
	fmt.Printf("slice4切片的值为:%v,slice4[0]的内存地址为:%p,slice4[1]的内存地址为:%p,slice4[2]的内存地址为:%p,\n", slice4, &slice4[0], &slice4[1], &slice4[2])
	slice4[0] = 10
	fmt.Printf("slice3的值为:%v\n", slice3)
	fmt.Printf("slice4的值为:%v\n", slice4)
}

执行结果

slice1切片的值为:[1 2 3 4 5 6 7 8]
slice2切片的值为:[9 10]                                                                                                           
slice1切片的值为:[9 10 3 4 5 6 7 8]                                                                                               
slice3切片的值为:[1 2 3],slice3[0]的内存地址为:0xc000010120,slice3[1]的内存地址为:0xc000010128,slice3[2]的内存地址为:0xc000010130,
slice4切片的值为:[1 2 3],slice4[0]的内存地址为:0xc000010120,slice4[1]的内存地址为:0xc000010128,slice4[2]的内存地址为:0xc000010130,
slice3的值为:[10 2 3]                                                                                                             
slice4的值为:[10 2 3]  

标签:slice4,切片,slice1,slice2,slice3,fmt,golang
From: https://www.cnblogs.com/LI-XinYu/p/17147048.html

相关文章

  • golang入门(十三)并发锁
    如果程序用到的数据是多个groutine之间的交互过程中产生的,那么使用上文提到的channel就可以解决了。如果我们的使用多个groutine访问和修改同一个数据,就需要考虑在并发环境......
  • 使用golang和bluge打造自己的全文搜索引擎
    全文搜索引擎有许多,其中最出名的是elasticsearch,无论是性能还是体验都是最顶尖的,但是对小应用来不友好,因为小应用的硬件资源比较少,所以能够通过库/模块的方式内置在应用中......
  • golang WEB框架Hertz --- 获取参数
    安装Hertz命令行工具请确保您的Go版本在1.15及以上版本,笔者用的版本是1.18配置好GO的环境后,按照Hertz的命名行工具goinstallgithub.com/cloudwego/hertz/cmd/hz@lates......
  • golang 字符串函数
    1.统计字符串的长度,按字节进行统计packagemainimport"fmt"funcmain(){ vars1string="hello,世界" fmt.Printf("s1字符串的长度为:%v",len(s1))//汉字为......
  • html2canvas截取不到openlayer地图(底图和注记等切片服务图层)解决方案
    第一步:设置所有切片图层服务的source对象,添加属性 crossOrigin: "anonymous",   //允许跨域   第二步:设置html2canvas配置项:   最后,附上html2canvas相......
  • golang 解析json数据
       packagemainimport(jsoniter"github.com/json-iterator/go")funcString2Bytes(datastring)[]byte{return[]byte(data)}funcmain(){......
  • MapReduce原理——切片代码分析
    (1)程序先找到数据存储的目录(2)遍历目录对每个文件进行切片(3)遍历一个文件:获取文件大小计算切片大小默认情况下,切片大小等于blocksize......
  • golang入门(十二)并发channel
    多线程与多进程本质的区别在于,多线程的内存空间是共享的,多进程是每一个进程都会独立开辟一块内存空间。如果我们运行的多个任务是完全独立的,那么在资源足够的情况下并发还是......
  • 03-Go数组、切片、可变长参数、maps
    1数组#1数组是类似于数字、字符串、的基础数据类型#2数组是同一类型元素的集合eg:整数集合:5,8,9,79,76形成一个数组Go--数组:不允许混合不同类型......
  • golang入门(十一)并发groutine
    并发与并行一直两个容易搞混的概念:并发:同一个时间段,共同运行的任务。任务的在这个时间段内,启动和结束的时间有先后之分的。举例来说:公司的食堂在中午12点-13点之间,可以容纳1......