你自学半年也搞不懂的go底层,看这篇。这篇讲 go的数组、切片、Maps
数组
1、定义数组
package main
import "fmt"
func main() {
//定义了一个大小为3的int类型数组
//数组在定义阶段,大小和类型就固定了
var a [3]int //只定义,没有初始化
fmt.Println(a)
}
//[0 0 0]
2、使用数组
package main
import "fmt"
func main() {
var a [3]int
a[2]=100 //修改赋值
fmt.Println(a)
fmt.Println(a[0]) //取0的位置
}
//[0 0 100]
//0
3、定义并赋值
package main
import "fmt"
func main() {
//方式一
var a [3]int=[3]int{1,2,3} //[1 2 3]
//方式二
var a =[3]int{1,2,3} //[1 2 3]
//方式三
a := [3]int{1, 2, 3} //[1 2 3]
//只给第2个位置设为99
a := [3]int{2:99} //[0 0 99]
//指定位置设置
a := [3]int{2:99,1:88} //[0 88 99]
fmt.Println(a)
}
4、数组的大小是类型的一部分
package main
import "fmt"
func main() {
//这两个不是一个类型
var a [2]int
var b [3]int
a=b
fmt.Println(a>b)
}
5、数组是值类型(当参数传递到函数中,修改不会改变原来的值)
// go语言中,都是copy传递
/*
python中都是引用传递,一切皆对象,就是地址,当做参数传递是把地址传过去了
python中比较特殊:可变类型和不可变类型
*/
package main
import "fmt"
func main() {
var a [3]int=[3]int{5,6,7}
fmt.Println(a) //[5 6 7]
test1(a)
fmt.Println(a) //[5 6 7]
}
func test1(a [3]int) {
a[0]=999
fmt.Println(a) //[999 6 7]
}
6、数组长度
package main
import "fmt"
func main() {
var a [3]int=[3]int{5,6,7}
fmt.Println(len(a)) //3
}
7、循环数组
package main
import "fmt"
func main() {
//方式一
var a [3]int=[3]int{5,6,7}
for i:=0;i<len(a);i++{
fmt.Println(a[i])
}
//方式二
//range:是一个关键字
var a [3]int=[3]int{5,6,7}
for i,v:=range a{
fmt.Println(i) //索引
fmt.Println(v) //数组的值
}
//方式三
//函数如果返回两个值,必须用两个值来接收
//range可以用一个值来接收,如果用一个值来接收,就是索引
var a [3]int=[3]int{5,6,7}
for i:=range a{
fmt.Println(i) //索引
}
//方式四
//只取值,不取索引
var a [3]int=[3]int{5,6,7}
for _,v:=range a{
fmt.Println(v) //值
}
}
8、多维数组
package main
import "fmt"
func main() {
//定义一个二维数组
var a [3][2]int // [[0 0] [0 0] [0 0]]
//定义并初始化
var a [3][2]int=[3][2]int{{1,2},{4,5},{9,70}}
a[1][0]=999 //修改值
fmt.Println(a) // [[1 2] [999 5] [9 70]]
}
切片
//切片是由数组建立的一种方便、灵活且功能强大的包装(Wrapper)。切片本身不拥有任何数据。它们只是对现有数组的引用。
//切片底层依附于数组
1、创建切片
package main
import "fmt"
func main() {
//创建切片(基于一个数组创建)
var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
//基于数组,切出一部分成为切片
// []int 中括号中没有东西,就是切片
var b []int
// 没有-1 没有步长
b=a[0:3] //前闭后开 //[1 2 3]
b=a[3:6] //前闭后开 //[4 5 6]
b=a[:] //前闭后开 //[1 2 3 4 5 6 7 8 9]
b=a[3:] //前闭后开 //[4 5 6 7 8 9]
fmt.Println(b)
}
2、使用切片
package main
import "fmt"
func main() {
var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
var b []int
b=a[3:] //前闭后开 //[4 5 6 7 8 9]
fmt.Println(b[0]) // 4
}
3、切片的修改会影响底层数组,数组的修个也会影响切片。相互影响
package main
import "fmt"
func main() {
var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
var b []int=a[0:3] //前闭后开
fmt.Println(a) //[1 2 3 4 5 6 7 8 9]
fmt.Println(b) //[1 2 3]
a[0]=999
b[2]=888
fmt.Println(a) //[999 2 888 4 5 6 7 8 9]
fmt.Println(b) //[999 2 888]
}
4、切片的长度和容量
package main
import "fmt"
func main() {
var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
var b []int=a[2:3] //前闭后开 //[3]
fmt.Println(len(b)) //1
//切片容量是7,意思是,可以往里追加值
fmt.Println(cap(b)) //7 还可以往后追加7个
//容量就是原数组的长度呗?对不对?不太对。。
b[0]=9999
fmt.Println(a) //[1 2 9999 4 5 6 7 8 9]
fmt.Println(b) //[9999]
}
5、追加值
//总结1:当切片追加值,超过了切片容量,切片容量会翻倍,在原来容量基础上乘以2
//总结2:一旦超过了原数组, 就会重新申请数组,把数据copy到新数组,切片和原数组就没有关系了
//总结3:追加值打破了原数据的容量,就不会再影响原数据
package main
import "fmt"
func main() {
var a [9]int=[9]int{1,2,3,4,5,6,7,8,9}
var b []int=a[2:3] //前闭后开 //[3]
b=append(b,1) //追加1
b=append(b,11,22,33,44,55) //继续追加
fmt.Println(len(b)) //7
fmt.Println(cap(b)) //7
fmt.Println(b) // [3 1 11 22 33 44 55]
fmt.Println(a) // [1 2 3 1 11 22 33 44 55]
//到了数组的尾部,继续追加值
b=append(b,999)
fmt.Println(len(b)) // 8
fmt.Println(cap(b)) //容量是14
//总结1:当切片追加值,超过了切片容量,切片容量会翻倍,在原来容量基础上乘以2
b=append(b,222,333,444,555,666,7,8)
fmt.Println(len(b)) //15
fmt.Println(cap(b)) //容量是14*2=28
//总结2:一旦超过了原数组, 就会重新申请数组,把数据copy到新数组,切片和原数组就没有关系了
fmt.Println(a)
fmt.Println(b)
a[8]=7777
fmt.Println(a)
fmt.Println(b)
}
6、通过make创建切片(底层也依附于数组)
package main
import "fmt"
func main() {
//var a []int
//切片零值是什么? nil类型:是所有引用类型的空值
//fmt.Println(a)
//if a==nil{
// fmt.Println("我是空的")
//}
//3是长度,4是容量
//var a []int=make([]int,3,4) //[0 0 0]
//3是长度,3是容量
var a []int=make([]int,3) //[0 0 0]
fmt.Println(a)
fmt.Println(len(a)) //3
fmt.Println(cap(a)) //3
a=append(a,55) // [0 0 0 55]
fmt.Println(a)
fmt.Println(len(a)) //4
fmt.Println(cap(a)) //6
}
7、切片定义并赋初值
package main
import "fmt"
func main() {
var a []int=[]int{1,2,3}
fmt.Println(a) //[1 2 3]
fmt.Println(len(a)) //3
fmt.Println(cap(a)) //3
}
8、切片是引用类型,当参数传递,会修改掉原来的值
package main
import "fmt"
func main() {
var a []int=[]int{1,2,3}
fmt.Println(a) // [1 2 3]
test3(a)
fmt.Println(a) // [999 2 3]
}
func test3(a []int) {
a[0]=999
fmt.Println(a) // [999 2 3]
}
9、多维切片
package main
import "fmt"
func main() {
var a [][]int=make([][]int,2,3)
fmt.Println(a) //[[] []]
fmt.Println(a[0]==nil) //true
//会报错
//a[0][0]=999
// 如何做?(for循环完成初始化)
a[0]=make([]int,2,3)
a[0][1]=999
fmt.Println(a) //[[0 999] []]
a[1][0]=99999
//
////定义并赋初值用的多
//var a [][]int=[][]int{{1,2,3},{4,5,6,7,7,8}}
//////跟上面不一样
//var a [][3]int=[][3]int{{1,2,3},{4,5,6}}
//fmt.Println(a)
}
10、切片的copy
package main
import "fmt"
func main() {
var a []int=make([]int,3,4)
var b []int=make([]int,2,6)
fmt.Println(a) //[0 0 0]
fmt.Println(b) //[0 0]
a[0]=11
a[1]=22
a[2]=33
b[0]=999
fmt.Println(a) // [11 22 33]
fmt.Println(b) // [999 0]
copy(b,a) //拷贝,把a拷给b,多余的截断
fmt.Println(b) // [11 22]
}
11、切片越界
package main
import "fmt"
func main() {
var a []int=make([]int,3,4)
fmt.Println(a) //[0 0 0]
a[0]=11
a[1]=22
a[2]=33
fmt.Println(a) //[11 22 33]
a=append(a,999) //追加
fmt.Println(a) //[11 22 33 999]
//中括号取值,只能取到长度值,不能取到容联大小
fmt.Println(a[3]) //999
fmt.Println(a[4]) //越界报错
}
Maps
//maps:hash,字典, key:value存储
1、map的定义和使用
package main
import "fmt"
func main() {
//map[key类型]value类型:key的类型必须可hash,key值:数字,字符串
//map的零值:nil 它是一个引用类型
var a map[int]string
fmt.Println(a) //map[]
if a==nil{
fmt.Println("我是空的") // 我是空的
}
}
2、定义了,没有初始化,使用
package main
import "fmt"
func main() {
//var a map[int]string
//初始化用make
var a map[int]string=make(map[int]string)
//如果有,会修改,如果没有,会放入
a[1]="lqz" // 设值
a[1]="jeff" //覆盖
a[2]="18"
//a["xx"] key值不能乱写
fmt.Println(a) //map[1:jeff 2:18]
}
3、获取元素
package main
import "fmt"
func main() {
var a map[int]string=make(map[int]string)
//var a map[int]int=make(map[int]int)
fmt.Println(a[0]) //取出value值的空值 ""
fmt.Println(a) // map[]
}
4、判断value值是否存在
package main
import "fmt"
func main() {
//统一的方案来判断value值是否存在
//a[0] 可以返回两个值,一个是value值(可能为空),另一个是true或false
var a map[int]int=make(map[int]int)
a[0]=0
v,ok:=a[0]
fmt.Println(v) //0
fmt.Println(ok) //true
}
5、map删除元素
package main
import "fmt"
func main() {
var a map[int]int=make(map[int]int)
a[1]=11
a[2]=22
fmt.Println(a) //map[1:11 2:22]
//根据key删(内置函数)
delete(a,1)
fmt.Println(a) //map[2:22]
}
6、map长度
package main
import "fmt"
func main() {
var a map[int]int=make(map[int]int)
fmt.Println(len(a)) //0
a[1]=11
a[2]=22
fmt.Println(len(a)) //2
}
7、map 是引用类型
package main
import "fmt"
func main() {
var a map[int]int=make(map[int]int)
a[1]=11
fmt.Println(a) // map[1:11]
test(a)
//证明是引用类型,相互改变
fmt.Println(a) // map[1:999]
}
func test(a map[int]int) {
a[1]=999
fmt.Println(a) //map[1:999]
}
8、map的相等性
//和python的字典差不多,只能按key取值后比较
package main
import "fmt"
func main() {
var a map[string]string=make(map[string]string)
a["name"]="lqz"
var b map[string]string=make(map[string]string)
b["name"]="lqz"
fmt.Println(a)
fmt.Println(b)
//不能这样判断,map只能跟nil比较
if a["name"]==b["name"] {
fmt.Println("相等")
}
}
9、循环map
//range循环
package main
import "fmt"
func main() {
var a map[string]string=map[string]string{"name":"lqz","age":"19","sex":"男"}
for k,v:=range a{
fmt.Println(k) //key
fmt.Println(v) //value
}
}
//map是无序的(python中字典从3.6以后有序了,3.6之前无序,底层如何实现的)
你自学半年也搞不懂的go底层,看这篇。这篇讲 go的数组、切片、Maps的更多相关文章
- 现在连Linux都搞不懂,当初我要是这么学习操作系统就好了!
原创声明 本文首发于微信公众号[程序员黄小斜] 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 简介 学习编程,操作系统是你必须要掌握的基础知识,那么操作系统到底是什么呢? 这还 ...
- 为什么你精通CRUD,却搞不懂数据库的基本原理?
原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图
- 那些年搞不懂的"协变"和"逆变"
博主之前也不是很清楚协变与逆变,今天在书上看到了有关于协变还是逆变的介绍感觉还是不太懂,后来看了一篇园子里面一位朋友的文章,顿时茅塞顿开.本文里面会有自己的一些见解也会引用博友的一些正文,希望通过本篇 ...
- 搞不懂的算法-排序篇<1>
最近在学习算法,跟着<Algorithms>这本书,可能是自己水平不够吧,看完排序算法后各种,希尔,归并,快排,堆的实现在脑子里乱成一锅粥,所以就打算大概总结一下,不求精确,全面,只想用平 ...
- 听说同学你搞不懂Java的LinkedHashMap,可笑
先看再点赞,给自己一点思考的时间,微信搜索[沉默王二]关注这个有颜值却假装靠才华苟且的程序员.本文 GitHub github.com/itwanger 已收录,里面还有我精心为你准备的一线大厂面试题 ...
- 什么鬼?你还搞不懂json和字典的区别??
现在自动化培训烂大街,是个人都能说的上几个框架,面试如果问框架相关问题,求职者只需一瓶 82 年的雪碧,会吹的让你怀疑人生!所以面试官为了更清楚的知道你是停留在表面上的花拳绣腿还是有扎实的基础,就不会 ...
- python3编码问题终结者--还搞不懂你来找我
python unicode bytes str 编码 首先需要说明一下,该篇文章是以python3为基础的,python2是否适合没有验证过.由于python编码问题确实比较多,文章篇幅可能较长,请 ...
- 搞不懂SSH与JAVA+Servlet+javabean有什么关系
在SSH中:struts 是控制层,同时与Jsp结合代表表现层,同时负责客户端请求的处理,Spring主要处理逻辑事物处理,Hibernate主要对数据库的持久化操作. Jsp+Servlet+Jav ...
- 搞不懂为什么开发人员爱iOS恨Android?
导读:很多网站发表文章大同小异.唯有这个不同点,给大家分享. Android和iOS的较量一直都是人们津津乐道的话题.两个平台各有各的优势所在,同时也都力图能在各个方面赶超对手.对于用户来说,青菜萝卜 ...
随机推荐
- 探索学习率设置技巧以提高Keras中模型性能 | 炼丹技巧
学习率是一个控制每次更新模型权重时响应估计误差而调整模型程度的超参数.学习率选取是一项具有挑战性的工作,学习率设置的非常小可能导致训练过程过长甚至训练进程被卡住,而设置的非常大可能会导致过快学习到 ...
- CSS3动画的使用以及优化
CSS3 动画 目录 1. 定义动画2. animation 属性3. animation 属性的兼容4. animation与transition 属性的取别5. animate.css 动画库6. ...
- HDU - 1962 二分图最大匹配模板(扑克牌得分最大)
题意: 直接说数据,第一行给定几组数据,每一组数据的第一行是两个人扑克牌分别的数量,第一行是亚当的扑克牌,第二行是夏娃的扑克牌,每一个扑克牌的大小用两个字符来表示,第一个表示是几号扑克牌,第二个表示扑 ...
- coding++:JS数组去重的几种常见方法
一.简单的去重方法 // 最简单数组去重法 /* * 新建一新数组,遍历传入数组,值不在新数组就push进该新数组中 * IE8以下不支持数组的indexOf方法 * */ function uniq ...
- 本地不安装Oracle时,PLSQL的配置
这篇我在csdn上写过的,文章地址:https://blog.csdn.net/weixin_40404606/article/details/101940542
- HFSS——平面正弦加载阿基米德螺旋线模型设计
这学期开始进入HFSS的学习,这是软件应该是电磁相关专业必须掌握的软件之一.前几天图老师发布第一个模型设计任务,是关于平面正弦加载阿基米德螺旋线,拿到具体要求后,就去网上找资料,发现有关HFSS的资料 ...
- MATLAB GUI设计(1)
一.新建GUI 1.命令行窗口输入 guide会出来如下界面,可以新建空白GUI,也可以打开已有GUI 2.通过工具栏新建 二.数据传递例子 1.添加输入框按钮,设置尺寸大小,内容,格式,标签 2.复 ...
- Java并发基础06. 线程范围内共享数据
假设现在有个公共的变量 data,有不同的线程都可以去操作它,如果在不同的线程对 data 操作完成后再去取这个 data,那么肯定会出现线程间的数据混乱问题,因为 A 线程在取 data 数据前可能 ...
- nexus Maven私服的相关配置
Maven私服中如需本地上传Maven私服内容则需在 setting.xml中配置如下: <server> <id>nexus-releases</id> < ...
- Java哈希表入门
Java哈希表(Hash Table) 最近做题经常用到哈希表来进行快速查询,遂记录Java是如何实现哈希表的.这里只简单讲一下利用Map和HashMap实现哈希表. 首先,什么是Map和HashMa ...