Go(03) slice切片的使用
原文链接
http://www.limerence2017.com/2019/05/08/golang05/#more
golang 的引用类型和内置类型变量
golang 中变量类型分为引用类型和值类型(也叫作内置类型)
1.值类型:变量直接存储值,内存通常在栈中分配。
值类型:基本数据类型int、float、bool、string以及数组和struct
2.引用类型:变量存储的是一个地址,这个地址存储最终的值。内存通常在 堆上分配。通过GC回收。
引用类型:指针、slice、map、chan等都是引用类型。这类型变量需要通过make构造
golang中函数传参只有一种方式
golang中函数传递参数,只有值传递一种,也就是实参内容按照值copy方式传递给形参。
当函数的形参变量类型为指针,slice,map,chan等类型时,虽然实参和形参地址不同,但是内部指向了同一个地址,所以可以达到修改指定空间数据的目的。
不要着急,接下来我会写一写小demo帮助大家理解。
数组
先把这段代码写一遍看看结果
1 |
//数组声明方法 |
上边提供了数组的声明方式 var 数组名 [数组长度] 元素类型,
同时给出了两种数组遍历方式:
1 len(数组名) 可以获取数组大小,然后遍历
2 采用range遍历,第一个返回值是索引,第二个返回值是对应的内容
int 类型数组初始值为0,指针类型数组初始值为nil
结果如下:
1 |
[0 0 0 0 0 0 0 0] |
前文说过数组是值类型变量,我们写个函数,在函数内部修改形参数组的变量内容,看是否会对实参影响
1 |
func modify(array [5]int) {
|
结果如下
1 |
In modify(), array values: [200 2 3 4 5] |
说明实参没有被函数修改。那么既然golang传递变量的方式都是值传递,是不是就没办法通过函数修改外部变量了呢?
肯定不是的,可以通过引用类型变量修改,比如指针,slice,map,chan等都可以在函数体内修改,从而影响外部实参的内容。
下面通过slice说明这一点
slice切片
先看代码
1 |
array := [5]int{1, 2, 3, 4, 5}
|
生成切片有三种方式
1 通过数组或者切片截取生成新的切片
2 通过make生成 如mkslice := make([]int, 5)
3 直接初始化 如mkslice3 := []int{1, 2, 3, 4, 5}
切片遍历和数组遍历类似,上面结果如下
1 |
Elements of array |
获取切片大小和容量
1 |
//获取size和capacity |
获取大小采用len,获取实际开辟的容量用cap
切片添加和删除
1 |
//末尾添加三个元素 |
采用append 方式可以添加切片数据,但是要注意将append赋值给要存储结果的slice
append有两种用法,第一种是多个参数,第一个参数是slice,后边是要加的多个元素。
第二种是第一个参数为slice,第二个参数为slice展开,slice…表示把slice中元素一个个展开加入。
切片的删除较为麻烦,比如说删除第n个元素,就是截取n-1之前的序列和n之后的序列进行拼接。
1 |
mkslice4 := make([]int, 0) //末尾添加三个元素 |
切片的copy
copy函数提供了切片的深层复制,而赋值操作(=)紧紧是浅拷贝。
看看赋值操作,我们修改slice内部元素数据,其他slice是否会受到影响
1 |
oldslice := []int{1, 2, 3, 4, 5}
|
输出一下
1 |
newslice is : [1 2 3] |
可以看到oldslice修改后,newslice和newslice2都受到影响了,即便他们地址不同。
为什么呢?这要追溯到slice内部实现
1 |
type Slice struct {
|
Slice 内部其实存放了一个指针ptr,这个ptr指向的地址就是存放数据连续空间的首地址,len表示空间当前长度,cap表示空间实际开辟了多大。
如下图
那如何深copy元素到另一个slice呢?就是copy函数了
1 |
slice1 := []int{1, 2, 3, 4, 5}
|
结果如下
1 |
after copy..... |
可以看到copy(destslice,srcslice),当destslice 大小< srcslice时,只拷贝destslice大小的数据。
也就是说copy的大小取决于destslice和srcslice最小值
另外copy后,修改slice2元素,slice1也不会受到影响,是深copy。
感谢关注我的公众号
Go(03) slice切片的使用的更多相关文章
- golang:slice切片
一直对slice切片这个概念理解的不是太透彻,之前学习python的就没搞清楚,不过平时就用python写个工具啥的,也没把这个当回事去花时间解决. 最近使用go开发又遇到这个问题,于是打算彻底把这个 ...
- golang slice切片的原理以及内置函数cap, len
golang中slice(切片)是常用的类型, slice是对数组进行封装 package main import ( "fmt" "strconv") fun ...
- python定制类(1):__getitem__和slice切片
python定制类(1):__getitem__和slice切片 1.__getitem__的简单用法: 当一个类中定义了__getitem__方法,那么它的实例对象便拥有了通过下标来索引的能力. c ...
- golang基础---Slice切片
切片Slice在go语言中是单独的类型(指向底层的数组),不同于python(对可迭代对象操作的工具),注意区分数组和slice的区别 定义一个空slice,格式var s []int,这种既没有长度 ...
- Go语言核心之美 3.2-slice切片
Slice(切片)是长度可变的元素序列(与之相应,上一节中的数组是不可变的),每一个元素都有同样的类型.slice类型写作[]T.T是元素类型.slice和数组写法非常像,差别在于slice没有指定长 ...
- Go - Slice 切片
概述 切片是一种动态数组,比数组操作灵活,长度不是固定的,可以进行追加和删除. len() 和 cap() 返回结果可相同和不同. 声明切片 //demo_7.go package main impo ...
- 3.9 Go Slice切片
3.9 Go Slice切片 Go语言切片(Slice) 切片是可动态变化的序列,是对数组的引用,引用类型,遵循引用传递的机制 slice类型写作[ ]T,T是slice元素类型,var s1 []i ...
- [日常] Go语言圣经-Slice切片习题
1.Slice(切片)代表变长的序列,序列中每个元素都有相同的类型,一个slice类型一般写作[]T,其中T代表slice中元素的类型:slice的语法和数组很像,只是没有固定长度而已,slice的底 ...
- golang 数组以及slice切片
老虞学GoLang笔记-数组和切片 数组 Arrays 数组是内置(build-in)类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值.在初始化后长度是固定的,无法修改其 ...
随机推荐
- Codeforces Round #581 (Div. 2) B. Mislove Has Lost an Array (贪心)
B. Mislove Has Lost an Array time limit per test1 second memory limit per test256 megabytes inputsta ...
- Flight HDU - 3499 (分层最短路)
Recently, Shua Shua had a big quarrel with his GF. He is so upset that he decides to take a trip to ...
- 面试题:Dubbo中zookeeper做注册中心,如果注册中心集群全都挂掉,发布者和订阅者之间还能通信么?
1.[提供者]在[启动]时,向注册中心zk [注册]自己提供的服务. 2.[消费者]在[启动]时,向注册中心zk [订阅]自己所需的服务. 可以的,消费者在启动时,消费者会从zk拉取注册的生产者的 ...
- C# MVC的默认页
MVC的默认页,其实是默认路由设置启动哪一个Controller的哪一个Action,在根目录的Global.asax.cs里面设置.是MVC项目里面的路由.將下面的controller和action ...
- 32.把数组排成最小的数(python)
题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. # -*- ...
- plsql 连不上64位oracle客户端
1)安装Oracle 11g 64位 2)安装32位的Oracle客户端( instantclient-basic-win32-11.2.0.1.0) 下载instantclient-basic-wi ...
- web文件夹上传下载方案
第一点:Java代码实现文件上传 FormFile file = manform.getFile(); String newfileName = null; String newpathname = ...
- POJ 2456 编程技巧之------二分查找思想的巧妙应用
Aggressive cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 18599 Accepted: 8841 ...
- 3105: [cqoi2013]新Nim游戏
貌似一道经典题 在第一个回合中,第一个游戏者可以直接拿走若干个整堆的火柴.可以一堆都不拿,但不可以全部拿走.第二回合也一样,第二个游戏者也有这样一次机会.从第三个回合(又轮到第一个游戏者)开始,规则和 ...
- windows如何正确下载补丁包
今天公司让给windows安装补丁,打开链接,我蒙蔽了,这么多包要下载哪个腻?下面来跟杨老师一起学习一下如何确定windows版本,下载正确的补丁包. 首先先看一下下载补丁的页面,懵~~ 登录你需要安 ...