【Go语言学习笔记】数据
目录
- 字符串
- 数组
- 数组初始化
- 指针
- 复制
- 切片
- 基本操作
- reslice
- append
- copy
- 字典
- delete
- map是引用类型
- 并发操作
字符串
字符串是不可变字节(byte)序列,其本身是一个复合结构
type stringStruct struct{str unsafe.Pointerlen int
}
头部指针指向字节数组,但没有null结尾,默认以utf-8编码粗出Unicode字符,字面量李允许使用十六进制、八进制和UTF编码格式。默认值是""而不是null。
使用"`"定义不做转移处理的原始字符串,支持跨行
func main() {s := `line\r\n,line 2`println(s)
}
- 支持
!=、==、<、>、+、+=操作符 - 允许以索引号访问字节数组,但不能获取元素地址
- 以切片语法返回子串时,其内部依旧指向原字节数组
- 使用for遍历字符串时,分byte和rune两种方式;
func main() {s := "哈喽"for i := 0; i < len(s); i++ { // bytefmt.Printf("%d: [%c]\n", i, s[i])}for i, c := range s { // rune 返回数组索引号 以及unicode字符fmt.Printf("%d: [%c]\n", i, c)}0: [å]1: [ ]2: [ ]3: [å]4: [ ]5: [½]0: [哈]3: [喽]}
数组
定义数组类型时,数组长度必须是非负整形常量表达式,长度是类型组成部分,所以,元素类型相同但是长度不同的数组不属于同一类型
func main() {d1 := [3]int{}d2 := [2]int{}d1 = d2 // cannot use d2 (variable of type [2]int) as type [3]int in assignment
}
数组初始化
var a [4]int // 元素自动初始化为0 [0 0 0 0]b := [4]int{2, 5} // 未提供初始值得元素自动初始化为0 [2 5 0 0]c := [4]int{5, 3: 100} // 可指定索引位置初始化 [5 0 0 100]d := [...]int{1, 2, 3} // 编译器按初始化值数量确定数组长度 [1 2 3]e := [...]int{10, 3: 100} // 支持索引初始化,但是数组长度与此有关 [10 0 0 100]fmt.Println(a, b, c, d, e)
对于结构等复合类型,可省略元素初始化类型标签
type user struct {name stringage byte}d := [...]user{{"Tome", 20}, // 省略了类型标签{"Mary", 18}}fmt.Printf("%#v\n", d)
在定义多维数组时,仅第一维度允许使用“…”
a := [2][2]int{{1, 2},{3, 4},}b := [...][2]int{{10, 20},{30, 40},}c := [...][2][2]int{{{1, 2},{3, 4},},{{10, 20},{30, 40},},}fmt.Println(a)fmt.Println(b)fmt.Println(c)[[1 2] [3 4]][[10 20] [30 40]][[[1 2] [3 4]] [[10 20] [30 40]]]
内置函数len和cap都返回第一维度长度;
如果元素类型支持==、!=操作符,那么数组也支持此操作
指针
要分清楚指针数组和数组指针的区别,指针数组是指元素为指针类型的数组,数组指针是获取数组变量的地址。
x, y := 10, 20a := [...]*int{&x, &y} // 指针数组p := &a // 数组指针fmt.Printf("%T,%v\n", a, a) //[2]*int,[0xc000018088 0xc0000180a0]fmt.Printf("%T,%v\n", p, p) //*[2]*int,&[0xc000018088 0xc0000180a0]// 获取任意元素地址println(&a, &a[0], &a[1])//数组指针可以直接用来操作元素c := [...]int{1, 2}d := &cd[1] += 10println(d[1])
复制
Go数组是值类型,赋值和传参操作都会复制整个数组数据。
func test(a [3]int) {println(&a, &a[0], &a[1], &a[2]) // 传参 0xc0000cbf40 0xc0000cbf40 0xc0000cbf48 0xc0000cbf50
}func main() {a := [...]int{1, 2, 3}println(&a, &a[0], &a[1], &a[2]) // 0xc0000cbf58 0xc0000cbf58 0xc0000cbf60 0xc0000cbf68b := aprintln(&b, &b[0], &b[1], &b[2]) //赋值 0xc0000cbf28 0xc0000cbf28 0xc0000cbf30 0xc0000cbf38test(a)
如果需要,可改用指针或者切片,以避免数据复制
func test(a *[3]int) {println(&a, &a[0], &a[1], &a[2]) // 指针传参 0xc00007bf50 0xc00007bf38 0xc00007bf40 0xc00007bf48
}func main() {a := [...]int{1, 2, 3}println(&a, &a[0], &a[1], &a[2]) // 0xc00007bf38 0xc00007bf38 0xc00007bf40 0xc00007bf48b := a[:]println(&b, &b[0], &b[1], &b[2]) //切片赋值 0xc00007bf58 0xc00007bf38 0xc00007bf40 0xc00007bf48var c = &a // 指针赋值 0xc00007bf68 0xc00007bf38 0xc00007bf40 0xc00007bf48println(&c, &c[0], &c[1], &c[2])test(&a)
切片
基本操作
切片本身并非动态数组或数组指针,内部通过指针引用底层数组,设定相关属性将数据读写操作限定在指定区域内。其本身是个只读对象,工作机制类似数组指针的一种包装。
x := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}x1 := x[:]x2 := x[2:5]x3 := x[2:5:7]x4 := x[4:]x5 := x[:4]x6 := x[:4:6]fmt.Println(x1, len(x1), cap(x1)) // [0 1 2 3 4 5 6 7 8 9] 10 10fmt.Println(x2, len(x2), cap(x2)) // [2 3 4] 3 8fmt.Println(x3, len(x3), cap(x3)) // [2 3 4] 3 5fmt.Println(x4, len(x4), cap(x4)) // [4 5 6 7 8 9] 6 6fmt.Println(x5, len(x5), cap(x5)) // [0 1 2 3] 4 10fmt.Println(x6, len(x6), cap(x6)) // [0 1 2 3] 4 6
属性cap表示切片所引用数组片段的真实长度,len用于限定可读的写元素数量。
cap表示切片引用数组的容量,该数组可以插入多少个元素,如果cap不够则需要扩容
x3 = append(x3, 1000)x3 = append(x3, 1001)fmt.Println(x3, len(x3), cap(x3)) // [2 3 4 1000 1001] 5 5println(&x3)x3 = append(x3, 1002)fmt.Println(x3, len(x3), cap(x3)) //cap不够,发生扩容,cap变成10 [2 3 4 1000 1001 1002] 6 10println(&x3)
可以直接创建切片对象,无须预先准备数组,因为是引用类型,须使用make函数或显
s1 := make([]int, 3, 5) // 指定len、cap底层数组初始化为零值s2 := make([]int, 3) // 省略cap 和len 相等s3 := []int{10, 20, 5: 30} // 按初始化元素分配底层数组,并设置 len、capfmt.Println(s1, len(s1), cap(s1)) // [0 0 0] 3 5fmt.Println(s2, len(s2), cap(s2)) // [0 0 0] 3 3fmt.Println(s3, len(s3), cap(s3)) // [10 20 0 0 0 30] 6 6
可以获取元素地址,但是不能向数组那样直接用指针访问元素内容
s := []int{0, 1, 2, 3, 4}p := &sp0 := &s[0]p1 := &s[1]println(p, p0, p1) // 0xc00007bf58 0xc00000a360 0xc00000a368(*p)[0] += 100 // *[]int 不支持索引操作 须先返回[]int对象 mismatched types []int and untyped int*p1 += 100fmt.Println(s) // [100 101 2 3 4]
reslice
对切片再次进行切片,不能超出cap,但是不受len限制。新切片对象依旧指向原底层数组,也就是说修改对所有关联切片可见。
d := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}s1 := d[3:7]s2 := s1[:3]s2[1] = 100println(&s1[0]) // 0xc000014298println(&s2[0]) // 0xc000014298fmt.Println(s1) // [3 4 100 6]fmt.Println(s2) // [3 100 5]
append
向切片尾部添加数据,返回新的切片对象
s := make([]int, 0, 5)s1 := append(s, 10)s2 := append(s1, 20, 30)fmt.Println(s, len(s), cap(s)) // [] 0 5fmt.Println(s1, len(s1), cap(s1)) // [10] 1 5fmt.Println(s2, len(s2), cap(s2)) // [10 20 30] 3 5
数据被追加到原底层数组,如超出cap限制,则为新切片对象重新分配数组。
copy
在两个切片对象间复制数据,允许指向同一底层数组,允许目标区间重叠,最终所复制长度以较短的切片长度为准。
d := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}s1 := d[5:8]n := copy(d[4:], s1) // 在同一底层数组的不同区间复制fmt.Println(n, d) // 3 [0 1 2 3 5 6 7 7 8 9]s2 := make([]int, 6)n = copy(s2, d) // 在不同数组间复制fmt.Println(n, s2) // 6 [0 1 2 3 5 6]
字典
字典是引用类型,使用make函数或初始化表达语句来创建。
m := map[string]int{"a": 1,"b": 2,}fmt.Println(m)m["a"] = 10 // 修改m["c"] = 30 // 新增if v, ok := m["d"]; ok { // 使用ok-idiom 判断key是否存在println(v)}delete(m, "d") // 删除键值对,不存在时,不会出错
访问不存在的键值对,默认返回零值,不会引发错误,但推荐使用ok-idiom模式,毕竟通过零值无法判断键值是否存在,或许存储的value本身就是零。
因内存访问安全和河西算法等缘故,字典被设计成“not addressable” 故不能直接修改value成员。
正确做法时返回整个value,待修改后再设置字典键值,或直接用指针类型。
type user struct {name stringage byte}m := map[int]user{1: {"Tome", 19},}//m[1].age += 1 // Cannot assign to m[1].ageu := m[1]u.age += 1m[1] = ufmt.Println(m) // map[1:{Tome 20}]m2 := map[int]*user{1: &user{"Jack", 20},}m2[1].age++
delete
在迭代期间删除或新增键值时安全的。
m := make(map[int]int)for i := 0; i < 10; i++ {m[i] = i + 10}for k := range m {if k == 5 {m[100] = 1000}delete(m, k)fmt.Println(k, m)}//1 map[0:10 2:12 3:13 4:14 5:15 9:19]//3 map[0:10 2:12 4:14 5:15 9:19]//4 map[0:10 2:12 5:15 9:19]//5 map[0:10 2:12 9:19 100:1000]//0 map[2:12 9:19 100:1000]//2 map[9:19 100:1000]//9 map[100:1000]
不能保证迭代操作会删除新增的键值
Go没有为map提供清空所有元素的函数,清空map唯一的办法是重新make一个新的map。
Go语言的垃圾回收比写一个清空函数更高效
map是引用类型
map与切片相似,都是引用类型。将一个map赋值给一个新的变量时,它们指向同一块内存,因此修改两个变量的内容都能够引起它们所指向的数据发生变化。
map1 := map[string]string{"hello":"123","demo":"321",}fmt.Println("原始map: ",map1)newMap := map1newMap["hello"]="456"fmt.Println("修改后newMap: ",newMap)fmt.Println("修改后map: ",map1)
// 原始map: map[demo:321 hello:123]
// 修改后newMap: map[demo:321 hello:456]
// 修改后map: map[demo:321 hello:456]
并发操作
运行时会对字典并发操作做出检测,如果某个任务正在对字段进行写操作,那么其他任务就不能对该字典并发操作,否则会导致进程崩溃。
m := make(map[string]int)go func() {for {m["a"] += 1 // 写操作time.Sleep(time.Millisecond)}}()go func() {for {_ = m["b"] // 读操作time.Sleep(time.Millisecond)}}()select {} // 阻止进程退出// fatal error: concurrent map read and map write
相关文章:
【Go语言学习笔记】数据
目录字符串数组数组初始化指针复制切片基本操作resliceappendcopy字典deletemap是引用类型并发操作字符串 字符串是不可变字节(byte)序列,其本身是一个复合结构 type stringStruct struct{str unsafe.Pointerlen int }头部指针指向字节数组…...
puzzle(0919)六宫数局
目录 六宫数局 示例题目 简单模式 普通模式 困难模式 六宫数局 最强大脑同款项目。 找出一条给定起点和终点的路径,每一步的方向任选,在这个方向上移动的步数是当前数的质因数分解中2、3、5的次数。 示例题目 按照六边形坐标系来建立坐标系&#…...
脑机接口科普0016——独立BCI与非独立BCI
本文禁止转载!!!! 所谓的“独立BCI”与“非独立BCI”仅仅是BCI系统中的一个术语。本章主要是介绍一下这两个术语。 这两个术语是由Wolpaw在2002年提出来的。 独立BCI是指不依赖于中枢神经系统的的输出。 非独立BCI是指那种依赖…...
女神节告白代码
今天是女神节,送给所有女神们一句话: 爱自己是终生浪漫的开始,无论何时都要好好爱自己 目录 1. 请求动画帧填充 2.点类 3.粒子类 编辑 4.ParticlePool 池类 5.创建和填充 6.处理循环队列 7.更新活动粒子 8.移除非活性粒子 9.绘制有…...
【数据结构】单链表:头部操作我很行,插入也不用增容!!!
单链表 文章目录单链表1.链表1.1链表的概念和结构1.2链表的分类2.单链表的模拟实现2.1单链表的打印2.2单链表的尾插2.3单链表的头插2.4单链表的尾删2.5单链表的头删2.6单链表的查找2.7单链表的中间插入(在结点前插入)2.8单链表的中间删除(删除该结点)2.9单链表的中间插入(在结点…...
SpringBoot——使用WebSocket功能
springboot自带websocket,通过几个简单的注解就可以实现websocket的功能; 启动类跟普通的springboot一样: /*** 2023年3月2日下午4:16:57*/ package testspringboot.test7websocket;import org.springframework.boot.SpringApplication; im…...
博弈论小课堂:非零和博弈(实现双赢)【纳什均衡点】
文章目录 引言I 非零和博弈1.1 囚徒问题1.2 博弈中双方的收益矩阵II 在现实中找均衡点2.1 博弈通常不是一次性的,而是反复进行的2.2 博弈论讲的都是阳谋的策略2.3 人类还处于文明的初级阶段,人的道德水准不容高估2.4 乌合之众效应2.5 很多时候看似是双赢,其实是在更大范围内…...
数组中的逆序对
解题思路1: 看到这个题目,我们的第一反应是顺序扫描整个数组。每扫描到一个数组的时候,逐个比较该数字和它后面的数字的大小。如果后面的数字比它小,则这两个数字就组成了一个逆序对。假设数组中含有n个数字。由于每个数字都要和…...
C++基础了解-01-基础语法
基础语法 一、基础语法 C 程序可以定义为对象的集合,这些对象通过调用彼此的方法进行交互。现在让我们简要地看一下什么是类、对象,方法、即时变量。 对象 - 对象具有状态和行为。例如:一只狗的状态 - 颜色、名称、品种,行为 -…...
phpmyadmin 文件包含(CVE-2014-8959)
0x01 漏洞介绍 phpMyAdmin是phpMyAdmin团队开发的一套免费的、基于Web的MySQL数据库管理工具。该工具能够创建和删除数据库,创建、删除、修改数据库表,执行SQL脚本命令等。phpMyAdmin的GIS编辑器中libraries/gis/GIS_Factory.class.php脚本存在目录遍历漏洞。远程攻击者可借助…...
SpringBoot集成MyBatis
目录 实现步骤 1. 在项目的 pom.xml 配置文件中引入如下依赖 2. 在项目的 application.properties 配置文件中添加如下依赖 3. 新建 UserMapper.class 接口类,添加如下 3 个方法 4. 在 /resources/mybatis/mapper 路径(需要手动创建文件夹)下创建 UserMapper.xm…...
MySQL-索引
索引介绍索引是对数据库表中一列或者多列的值进行排序的一种结构,使用索引可提高数据库中特定数据的查询速度。索引是一个单独的、存储在磁盘上的数据库结构,它们包含着对数据表里所有记录的引用指针。使用索引用于快速找出在某个或多个列中有一特定值得…...
【STM32存储器映射-寄存器基地址-偏移】
前言 在学习STM32的时候,我们看到很多的寄存器编程, 比方说LED灯: //GPIOB.5端口输出高电平GPIOB->ODR|1<<5; //PB.5 输出高GPIOE->ODR|1<<5; //PE.5输出高 //GPIOB端口全部输出高电平*(unsigned int*)(0x4001 …...
【华为OD机试2023】最多颜色的车辆 C++ Java Python
【华为OD机试2023】最多颜色的车辆 C++ Java Python 前言 如果您在准备华为的面试,期间有想了解的可以私信我,我会尽可能帮您解答,也可以给您一些建议! 本文解法非最优解(即非性能最优),不能保证通过率。 Tips1:机试为ACM 模式 你的代码需要处理输入输出,input/cin接收…...
特斯拉后端面试(部分)
HR告知如果面试通过要转.net-_- round1 有没有用过Java新版本,知道有哪些特性吗?A:没有。Q:我们基本在用JDK11,有的新项目用到JDK17了。参考答案1: ZGC: A Scalable Low-Latency Garbage Collector Epsi…...
【python】使用python将360个文件夹里的照片,全部复制到指定的文件夹中,并且按照顺序重新命名
最近要做一个图像生成的课题,在网上找了一个混合的数据集。这个数据集中一共有360个文件夹,然后文件夹中有6-9张不等的照片,我的目标就是编写python代码将所有的照片取出来,放到一个指定的文件夹里,并且从1开始按照顺序…...
【C语言】3天速刷C语言(初识)
【声明】本篇博客只用于对与刚学习C语言的同学的一个初始了解,具体内容请继续关注本专栏后续内容。什么是C语言C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及…...
如何搞定MySQL锁(全局锁、表级锁、行级锁)?这篇文章告诉你答案!太TMD详细了!!!
概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题&…...
云计算生态该怎么做?阿里云计算巢打了个样
2023 年 2 月 23 日至 24 日,由阿里云主办的「阿里云计算巢加速器」于杭州阿里云谷园区集结。 阿里云计算巢加速器于 2022 年 8 月正式启动招募,最终百奥利盟、极智嘉、EMQ、KodeRover、MemVerge 等 30 家创新企业入选计算加速器,覆盖了人工智…...
小樽C++ 多章⑧ (贰) 指针与数组
目录 1.C中数组变量名某些情况可以看成是指针 2.C语言的scanf 输入语句,printf 输出语句 3.用指针来当动态数组 小樽C 多章⑧ (壹) 指针变量https://blog.csdn.net/weixin_44775255/article/details/129031168 小樽C 多章⑧ (叁) 指针与字符串、(肆) 函数与指针…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
webpack面试题
面试题:webpack介绍和简单使用 一、webpack(模块化打包工具)1. webpack是把项目当作一个整体,通过给定的一个主文件,webpack将从这个主文件开始找到你项目当中的所有依赖文件,使用loaders来处理它们&#x…...
