golang中数组与切片的区别
初始化:数组需要指定大小,不指定也会根据初始化的自动推算出大小,不可改变
数组:
a := [...]int{,,}
a := []int{,,}
切片:
a:= []int{,,}
a := make([]int, )
a := make([]int, , )
slice的数据结构:
go源码slice的数据结构定义:
type slice struct {
array unsafe.Pointer
len int
cap int
}

一个指向真实 array 地址的指针 ptr ,slice 的长度 len 和容量 cap
函数传递:数组需要明确指定大小,切片不需要。数组是值传递,切片是地址传递
numbers2 := [...]int{, , , , , }
maxIndex2 := len(numbers2) -
for i, e := range numbers2 {
if i == maxIndex2 {
numbers2[] += e
} else {
numbers2[i+] += e
}
}
fmt.Println(numbers2)
numbers3 := []int{, , , , , }
maxIndex3 := len(numbers3) -
for i, e := range numbers3 {
if i == maxIndex3 {
numbers3[] += e
} else {
numbers3[i+] += e
}
}
fmt.Println(numbers3)
输出:
[ ]
[ ]
观察slice append的时候内存地址会不会改变:
通过一个例子:
package main import (
"fmt"
"unsafe"
) func main() {
//说先定义一个切片,只限定长度为1
s := make([]int, 1) //打印出slice的长度,容量以及内存地址
fmt.Printf("len :%d cap:%d array ptr :%v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s))) for i := 0; i < 5; i++ {
s = append(s, i)
fmt.Printf("len :%d cap:%d array ptr :%v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s)))
}
//打印出slice
fmt.Println("array:", s)
}
输出:
len : cap: array ptr :0xc042062080
len : cap: array ptr :0xc0420620c0
len : cap: array ptr :0xc0420600e0
len : cap: array ptr :0xc0420600e0
len : cap: array ptr :0xc0420880c0
len : cap: array ptr :0xc0420880c0
array: [ ]
可以看出来在append的过程中,内存地址有些是一样的,有些是不一样的,容量也是如此
看出来了吧,每次cap改变的时候指向array内存的指针都在变化。当在使用 append 的时候,如果 cap==len 了这个时候就会新开辟一块更大内存,然后把之前的数据复制过去。
- 而cap是以乘以2的速度扩展的。这里是不是真的就是乘以2的速度呢??
- 最后一句输出slice元素的时候为什么会多了一个0呢??
对于问题2:是因为make初始化时,都会初始化成对应数据类型的原值
我们再来测试一下问题1:
package main import (
"fmt"
"unsafe"
) func main() {
//说先定义一个切片,只限定长度为1
s := make([]int, ) //打印出slice的长度,容量以及内存地址
fmt.Printf("len :%d cap:%d array ptr :%v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s))) for i := ; i < *; i++ {
s = append(s, i)
fmt.Printf("len :%d cap:%d array ptr :%v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s)))
}
//打印出slice
fmt.Println("array:", s)
}
输出太多了,就截一部分:

如果按照上面得出的结论,那cap为1024的下一个应该是2048,但是却是1280
实际go在append的时候放大cap是有规律的。在 cap 小于1024的情况下是每次扩大到 * cap ,当大于1024之后就每次扩大到 1.25 * cap 。
golang中数组与切片的区别的更多相关文章
- GoLang笔记-数组和切片,本质是就是长度不可变的可变的区别
数组 Arrays 数组是内置(build-in)类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值.在初始化后长度是固定的,无法修改其长度.当作为方法的入参传入时将复制一份数 ...
- Golang数组和切片的区别
大纲 数组是固定大小 切片不是动态数组,可以扩容 区别 定义方式不一样 初始化方法不一样 package main import "fmt" func main() { // -- ...
- golang中数组指针与指针数组的区别实现
指针数组和数组的指针,指的是两个不同的东西. 指针数组是有指针组成的数组,数组的指针是一个数组的指针. package main import "fmt" const MAX ...
- Go数组和切片你不知道的区别
开篇语 数组和切片是两种不同的数据结构,比较常见,在Go语言中同时存在,今天我们就一起来看看他们在使用方式上,原理上的一些区别? 数组 在Go语言中,数组是一种具有相同类型固定大小的一种数据结构. 我 ...
- golang笔记——数组与切片
一.切片的定义 我们可以从数组(go语言中很少直接使用数组)或者切片来初始化一个新的切片,也可以直接通过 make 来初始化一个所有元素为默认零值的切片. //1.通过数组来初始化切片 arr := ...
- [Go] gocron源码阅读-go语言中数组和切片的字面值初始化语法
源码中有这么一句,这个函数要求返回的是[]cli.Command,cli.Command类型的切片,这个地方直接使用字面值初始化了一个切片返回去了 return []cli.Command{comma ...
- golang之数组与切片
数组 数组可以存放多个同一类型数据,数组也是一种数据类型,在Go中,数组是值类型. 数组的定义: var 数组名 [数组大小]数据类型 var a [5]int 赋初值 a[0] = 1 a ...
- 『GoLang』数组与切片
数组 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列(这是一种同构的数据结构):这种类型可以是任意的原始类型例如整型.字符串或者自定义类型. 数组长度必须是一个常量表达式,并且必须是一个非负 ...
- c语言中数组的定义和java中数组定义的一些区别
感谢原文:https://blog.csdn.net/gzwdz778/article/details/79799408 一维情况下: c中,数组的声明需要给出数组的维数,比如: int arr[5] ...
随机推荐
- Eureka自我保护模式——难点重点
一.开启Eureka自我保护模式访问Eureka主页时,如果看到这样一段大红色的句子: EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ...
- Haproxy+Heartbeat 高可用集群方案操作记录
之前详细介绍了haproxy的基础知识点, 下面记录下Haproxy+Heartbeat高可用web集群方案实现过程, 以加深理解. 架构草图如下: 1) 基本环境准备 (centos6.9系统) 1 ...
- JavaWeb学习 (二十八)————文件上传和下载
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- 【Spring】详解spring事务属性
Spring声明式事务让我们从复杂的事务处理中得到解脱.使得我们再也无需要去处理获得连接.关闭连接.事务提交和回滚等这些操作.再也无需要我们在与事务相关的方法中处理大量的try…catch…final ...
- JAVA对Excel的导入导出
今天需要对比2个excel表的内容找出相同:由于要学的还很多上手很慢所以在这做个分享希望对初学的有帮助: 先是pom的配置: <dependency> <groupId>org ...
- springboot整合freemarker----一点小小的错误
最近小弟正在学习springboot,没办法,现在微服务太火了.小弟也要顺应时代的潮流啊 :( 好了,废话不多说了!!!! 首先在springboot的pom.xml添加freemarker的依赖 & ...
- CSS水平居中的三种方法
CSS中经常会用到元素居中,那么今天我为大家分享几种水平居中的方法,下面代码都可以达到同样的居中效果,来不及解释了,快上马(码): 一.margin : 0 auto; <head> &l ...
- python自动化开发-6
python的常用模块(续) shutil模块:主要是做文件复制的.文件,文件夹,压缩包等的处理模块. 常用的方法: shutil.copyfileobj:将文件的内容拷贝到另一个文件中. 例子: # ...
- 惊闻企业Web应用生成平台 活字格 V4.0 免费了,不单可视化设计器免费,服务器也免费!
官网消息: 针对活字格开发者,新版本完全免费!您可下载活字格 Web 应用生成平台 V4.0 Updated 1,方便的创建各类 Web 应用系统,任意部署,永不过期. 我之前学习过活字格,也曾经向用 ...
- Keras 中 TimeDistributed 和 TimeDistributedDense 理解
From the offical code: class TimeDistributed(Wrapper): """This wrapper applies a laye ...