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] ...
随机推荐
- Nginx实战-后端应用健康检查
严格来说,nginx是没有针对负载均衡后端节点的健康检查的,但是可以通过proxy_next_upstream来间接实现,但这个还是会把请求转发给故障服务器的,然后再转发给别的服务器,这样就浪费了一次 ...
- #10 Python字符串
前言 通过上一节可知,Python6个序列的内置类型中,最常见的是列表和元组,但在Python中,最常用的数据类型却不是列表和元组,而是字符串.要想深入了解字符串,必须先掌握字符编码问题.因此本篇博文 ...
- 【学习笔记】AJAX内容拓展
题记——近期回顾<javaScript高级程序设计>ajax章节,发现书中对封装一个ajax库并不完美,结合之前看到博客,对ajax库做一点点的优化. 参考博客:如何去封装一个ajax库 ...
- ServerSocket和Socket
前言 用ServerSocket和Socket做了个Server.Client通信的demo,以及学习下在这个demo过程中用到java.net.java.io包下几个常用的类. Server imp ...
- [转]angular2中ng alerts的使用教程
本文转自:https://blog.csdn.net/m0_37981481/article/details/79281879 由于想要一个好看的alert,于是去npm上搜了一下,手动捂脸,npm上 ...
- 【ichart】简单的统计图表ichart.js的使用
1.首先下载,点击下载 2.只需要这一个js,粘贴赋值到自己项目中即可. 3.引入js <script type="text/javascript" src=" ...
- Aspose.Cells API 中文版文档 下载
链接: https://pan.baidu.com/s/19foJyWgPYvA7eIqEHJ_IdA 密码: yxun
- What are the differences between a pointer variable and a reference variable in C++?
Question: I know references are syntactic sugar, so code is easier to read and write. But what are t ...
- 理解es6中的const与“不变”
const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动. 效果 对于简单类型的数据(数值.字符串.布尔值),值就保存在变量指向的那个内存地址,因此等同于常量. 对于复合类型 ...
- Confluence设置MySQL数据库报错:必须使用'READ-COMMITTED'作为默认隔离级别。
解决方案: mysql -u root -p123456 SET GLOBAL tx_isolation='READ-COMMITTED'; mysql数据库创建 1.设置mysql隔离级别 SET ...