Golang基础2-Array、Slice、Map

Array

数组

    1. var a [5]int b:=[5]int{} c:=[...]int{}这样格式定义
    2. var a[5]int 和var a[10]int是不同类型
    3. 从0开始下标,到len(a)-1
    4. 遍历方式:
for i := 0; i < len(a); i++ {
}for index, v := range a {
}
    1. 注意越界问题,panic
    2. 值类型,传参时会拷贝产生副本,不是指针 (因此会有性能问题)可以考虑传指针或者slice等引用类型
    3. 指针数组 [n]*T 数组指针 *[n]T。

简单demo

package mainimport "fmt"// 定义数组测试
func Test1() {var a [5]intb := [...]float64{1, 2, 3}//cap和len都会输出数组长度lenA := cap(a)lenB := len(b)fmt.Println(a, lenA)fmt.Println(b, lenB)//[0 0 0 0 0] 5//[1 2 3] 3
}// 循环输出测试
func PrintArr(arr [5]int) {//对比地址可以发现是拷贝的值fmt.Println(&arr[0])//循环输出元素测试for i := 0; i < len(arr); i++ {fmt.Println(i, "->", arr[i])}fmt.Println("***********************")for index, value := range arr {fmt.Println(index, "->", value)}
}func main() {//Test1()arr := [5]int{1, 2, 3, 4}fmt.Println(&arr[0])PrintArr(arr)
}

Slice

切片

最常用,最重要类型之一

变长序列,引用了数组对象,灵活

指针(底层数组,但不一定数组首地址),长度len,容量cap

初始化demo

package mainimport "fmt"func main() {//var arr1 [5]int//声明切片,注意与数组对比var s1 []intif s1 == nil {fmt.Println("初始化为空!")} else {fmt.Println("不为空!")}fmt.Println(s1)// :=s2 := []int{}fmt.Println(s2)// make方式 len(2) cap(3)var s3 []int = make([]int, 2, 3)fmt.Println(s3, "len(s3)=", len(s3), " cap(s3)=", cap(s3))//len(4) cap(4)s4 := make([]int, 4)fmt.Println(s4, "len(s4)=", len(s4), " cap(s4)=", cap(s4))//从数组中切片arr := [5]int{1, 2, 3, 4, 5}//左[  右)s6 := arr[1:4]fmt.Println(s6)
}

简单理解slice底层demo

具体源码在src/runtime/slice.go当中

package mainimport "fmt"func main() {arr := [6]int{0, 1, 2, 3, 4, 5}x := arr[:6]y := arr[1:3]fmt.Println(arr)fmt.Println(x, y)//    [0 1 2 3 4 5]//    [0 1 2 3 4 5] [1 2]fmt.Println()arr[1] = 100fmt.Println(arr)//实际操作底层数组fmt.Println(x, y)//    [0 100 2 3 4 5]//    [0 100 2 3 4 5] [100 2]fmt.Println()x[2] = 200fmt.Println(arr)//实际操作底层数组fmt.Println(x, y)
}

追加元素append demo

共享内存下容易出现的bug,请仔细分析

老数组

初始化时若:newSlice := array[1:2:2] ,如果第三个值(cap(slice))大于len(slice)

cap>len的时候请注意共享内存下的数据。

package mainimport "fmt"// 切片len<cap 注意会影响共享内存下的值
func main() {array := [4]int{10, 20, 30, 40}slice := array[0:2]newSlice := append(slice, 300)//这两个很有区别,这个扩容超出cap进行重新分配//newSlice := append(slice, 300, 400, 500)fmt.Println(slice, newSlice)fmt.Printf("&slice=%p &newSlice=%p\n", &slice, &newSlice)fmt.Printf("&slice[0]=%p &newSlice[0]=%p\n", &slice[0], &newSlice[0])fmt.Println(slice, newSlice, array)newSlice[1] = 200fmt.Printf("&slice=%p &newSlice=%p\n", &slice, &newSlice)fmt.Printf("&slice[0]=%p &newSlice[0]=%p\n", &slice[0], &newSlice[0])fmt.Println(slice, newSlice, array)
}

新数组:

扩容策略,即内存不够的时候重新分配array数组

当cap比较小的时候,扩容直接2倍

随着增大就扩容1/3,1/4等等逐渐减少

新数组扩容demo

package mainimport "fmt"// 了解分配策略
func main() {//初始化sliceslice := []int{0}c := cap(slice)num := 0 //计数,扩容次数for i := 0; i < 1024; i++ {//添加前cappreArr := &slice[0]preSlice := &sliceslice = append(slice, i)//添加后cap变大了就代表扩容了if n := cap(slice); n > c {fmt.Println("cap:", c, " --> ", n)fmt.Printf("  扩容前后底层array地址:%p --> %p\n", preArr, &slice[0])fmt.Printf("  扩容前后slice地址:%p --> %p\n\n", preSlice, &slice)c = nnum++}}fmt.Println("扩容了", num, "次!")}

总结:对于slice append造成扩容时,其slice的地址&slice不变,变化的是其内部array的地址

Slice详解分析:

https://halfrost.com/go_slice/

删除切片某元素demo

go语言并没有删除切片元素的接口,因此只能根据特性删除,[:]

删除开头元素:

    //方法1:移动array的指针   s := []int{1, 2, 3, 4}fmt.Printf("%#v\n", s)//fmt.Println(unsafe.Sizeof(int(0)))fmt.Printf("&s = %p\n", &s)fmt.Printf("&s[0] = %p\n\n", &s[0])//删除前两个元素,把底层的ptr向右移动s = s[2:]fmt.Printf("%#v\n", s)fmt.Printf("&s = %p\n", &s)fmt.Printf("&s[0] = %p\n\n", &s[0])//方法2:不改变array指针,但是代价是后面array数据向前移动s := []int{1, 2, 3, 4}fmt.Printf("&s = %p\n", &s)fmt.Printf("&s[0] = %p\n\n", &s[0])//删除掉a[0]s = append(s[:0], s[1:]...)fmt.Printf("%#v\n", s)fmt.Printf("&s = %p\n", &s)fmt.Printf("&s[0] = %p\n\n", &s[0])//方法3:copy函数辅助s := []int{1, 2, 3, 4}fmt.Printf("%#v\n", s)fmt.Printf("&s = %p\n", &s)fmt.Printf("&s[0] = %p\n\n", &s[0])//删除掉a[0] a[1]s = s[:copy(s, s[2:])]fmt.Printf("%#v\n", s)fmt.Printf("&s = %p\n", &s)fmt.Printf("&s[0] = %p\n\n", &s[0])

删除中间元素

    s := []int{0, 1, 2, 3, 4, 5, 6, 7}fmt.Printf("%#v\n", s)fmt.Printf("&s = %p\n", &s)fmt.Printf("&s[0] = %p\n\n", &s[0])//删除a[3]//s = append(s[:3], s[4:]...)//s = s[:3+copy(s[3:], s[4:])] // 删除中间1个元素//删除a[3]之后的3个元素//s = append(s[:3], s[6:]...)s = s[:3+copy(s[3:], s[6:])] // 删除中间1个元素fmt.Printf("%#v\n", s)fmt.Printf("&s = %p\n", &s)fmt.Printf("&s[0] = %p\n\n", &s[0])

删除尾部元素

a = []int{1, 2, 3}
a = a[:len(a)-1] // 删除尾部1个元素
a = a[:len(a)-N] // 删除尾部N个元素

切片删除元素:Go语言从切片中删除元素

container/list

这个是container中的list使用,也常见,了解即可。

package mainimport ("container/list""fmt"
)func main() {var mylist = list.List{}mylist.PushBack(123)mylist.PushBack(456)mylist.PushBack(789)fmt.Println(mylist)// 遍历listfor i := mylist.Front(); i != nil; i = i.Next() {fmt.Println(i.Value)}fmt.Println("--------------")for i := mylist.Back(); i != nil; i = i.Prev() {fmt.Println(i.Value)}// 其他需求,自己查阅资料}

https://juejin.cn/post/6888117219213967368#heading-2

Map

哈希表,无序key/value键值对

map[keyType][valueType] ,key是唯一的,其对应的value也唯一

map必须初始化才能读写,否则只能读

线程不安全,在多线程当中使用sync.Map,我编辑在了并发编程当中

简单demo

package mainimport "fmt"// 全局初始化
var map1 map[int]stringfunc main() {//等价//可以声明时初始化//scoreMap := map[string]int{}//可以声明初始化空间scoreMap := make(map[string]int, 0)scoreMap["张三"] = 100scoreMap["赵六"] = 10scoreMap["李四"]=60// 双参数返回,val,ok,如果单参数val,!ok返回空,有可能key是空if value, ok := scoreMap["张三"]; ok {fmt.Println(value)} else {fmt.Println("查无此人")}fmt.Println(scoreMap)fmt.Printf("%#v\n", scoreMap)// 删除key,valuedelete(scoreMap, "张三")fmt.Println(scoreMap)fmt.Printf("%#v\n", scoreMap)
}

输出是没有顺序的,如果想要按照一定顺序,可以先取出key,然后排序,之后输出。

key对应一个value,其中如果value切片的话会很灵活,map类型的切片也很灵活

对map进行打印

    var courseMap = map[string]string{"go":   "go语言圣经","gin":  "深入理解gin框架","grpc": "grpc理解",}for key, value := range courseMap {fmt.Println(key, "-->", value)}fmt.Println("---------------")for key := range courseMap {fmt.Println(key, "-->", courseMap[key])}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/827726.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

密码学 | Schnorr 协议:零知识身份证明和数字签名

&#x1f955;原文&#xff1a; Schnorr 协议&#xff1a;零知识身份证明和数字签名 &#x1f955;写在前面&#xff1a; 本文属搬运博客&#xff0c;自己留存学习。文中的小写字母表示标量&#xff0c;大写字母表示椭圆曲线中的点。 1 Schnorr 简介 Schnorr 由德国数学家和密…

windows系统下python开发工具安装

一. 简介 前一篇文章学习了安装 python解释器&#xff0c;文章如下&#xff1a; windows系统下python解释器安装-CSDN博客 本文来学习如何下载安装 python开发工具 PyCharm。 二. python开发工具 PyCharm下载安装 1. PyCharm官网 PyCharm开发工具 PyCharm为 python代码…

Llama网络结构介绍

LLaMA现在已经是开源社区里炙手可热的模型了&#xff0c;但是原文中仅仅介绍了其和标准Transformer的差别&#xff0c;并没有一个全局的模型介绍。因此打算写篇文章&#xff0c;争取让读者不参考任何其他资料把LLaMA的模型搞懂。 结构 如图所示为LLaMA的示意图&#xff0c;由…

域名被污染了只能换域名吗?

域名污染是指域名的解析结果受到恶意干扰或篡改&#xff0c;使得用户在访问相关网站时出现异常。很多域名遭遇过污染的情况&#xff0c;但是并不知道是域名污染&#xff0c;具体来说&#xff0c;域名污染可能表现为以下情况&#xff1a;用户无法通过输入正确的域名访问到目标网…

Windos环境下配置免费SSL证书详细步骤

获取免费证书 配置本机模拟域名 打开如下目录&#xff0c;hosts文件 C:\Windows\System32\drivers\etc 添加如下配置并保存 127.0.0.1 im.test.com下载安装 OpenSSL 下载链接 进入bin目录&#xff0c; 打开cmd窗口 执行如下命令&#xff0c;生成RSA私钥 ## 使用des3…

大型集团企业 怎么实现多区域文件交换?

很多大型集团企业&#xff0c;都会在全国各地&#xff0c;甚至海外&#xff0c;都设立分支机构&#xff0c;还有银行、邮政这类机构&#xff0c;都会在全国各地设立多个支行和网点&#xff0c;所以在日常经营过程中&#xff0c;都会存在多区域文件交换的场景。 大型集团企业在进…

JVM垃圾收集器--分区收集器

G1收集器 G1&#xff08;Garbage-First Garbage Collector&#xff09;在 JDK 1.7 时引入&#xff0c;在 JDK 9 时取代 CMS 成为了默认的垃圾收集器。G1 有五个属性&#xff1a;分代、增量、并行、标记整理、STW。 分代 G1收集器 将内部分为多个大小相等的区域&#xff0c;另…

Unity Shader 图形学【笔记一】

游戏图形学 源自&#xff1a;计算机图形学 涵盖&#xff1a;图形、动画的创建渲染展示 目标&#xff1a;性能优化、提高视觉质量&#xff0c;增强用户体验 技术&#xff1a;三维模型、纹理、光照、阴影、特效、动画、物理模拟、碰撞检测等 Unity Shader 是&#xff1a;un…

基于Vue+ElementPlus自定义带历史记录的搜索框组件

前言 基于Vue2.5ElementPlus实现的一个自定义带历史记录的搜索框组件 效果如图&#xff1a; 基本样式&#xff1a; 获取焦点后&#xff1a; 这里的历史记录默认最大存储10条&#xff0c;同时右侧的清空按钮可以清空所有历史记录。 同时搜索记录也支持点击搜索&#xff0c;按…

371D - Vessels

思路&#xff1a;用并查集维护&#xff0c;如果当前容器没有满&#xff0c;就指向自己&#xff0c;否则指向下一个容器。 这样就可以快速 find 到下一个没有满的容器&#xff0c;从而模拟询问 1。 代码&#xff1a; void solve(){int n;cin >> n;vector<int>p(n …

leetcode:滑动窗口----3. 无重复字符的最长子串

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: 输入: s "bbbbb" 输出: 1 解释: 因为…

算法竞赛相关问题总结记录

前言 日常在校生或者是工作之余的同学或多或少都会参加一些竞赛,参加竞赛一方面可以锻炼自己的理解与实践能力&#xff0c;也能够增加自己的生活费&#xff0c;竞赛中的一些方案也可以后续作为自己论文的base,甚至是横向课题的框架。在算法竞赛中算法的差别个人感觉差距都不大&…

一招搞定“找不到xinput1_3.dll,无法继续执行代码”问题

在我们日常使用电脑进行各类工作的过程中&#xff0c;特别是在运行一些关键性软件以完成特定任务时&#xff0c;电脑屏幕上突然弹出一条醒目的错误提示信息&#xff1a;“由于找不到xinput1_3.dll,无法继续执行代码”。这个错误通常发生在使用DirectInput库时&#xff0c;而xin…

BFS解决FloodFill算法:(Leetcode:733. 图像渲染)

题目链接&#xff1a;733. 图像渲染 - 力扣&#xff08;LeetCode&#xff09; 使用广度优先遍历算法解决该问题&#xff1a; 从初始位置开始搜索&#xff0c;初始位置符合条件就入栈&#xff0c;并修改初始位置值。初始位置出栈。 再从初始位置开始广度优先搜索&#xff08;…

阿赵UE学习笔记——30、HUD简单介绍

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   继续学习虚幻引擎&#xff0c;这次来学习一下HUD的基础使用。 一、 什么是HUD HUD(Head-Up Display)&#xff0c;也就是俗称的抬头显示。很多其他领域里面有用到这个术语&#xff0c;比如开车的朋友可能会接触过&#xf…

【Camera Sensor Driver笔记】一、Sensor基本概念

时钟 sensor clock sensor的输入时钟 MCLK 输出时钟&#xff1a; 1. VTPixelClock&#xff1a;会影响sensor内部的帧率、曝光 VTPixelClock(vt_clk)Video Timing Clock, From sensor PLL VTPixelClock Framelengthlines x LinelengthPixelClock x FPS Framelengthlines L…

页面加载事件

2.1窗口加载事件 1.window.οnlοadfuction(){} 或者 window.addEventListerner(‘load’,function(){}) doucument.addEventListner(DOMContentLoaded,fuction(){})这个反应更快些

是德软件89600 RFID使用笔记

文章目录 1、进入RFID软件&#xff1a;2、RFID软件解调设置项3、如何查看一段指令数据 本文是日常工作的笔记分享。 lauch VSA&#xff08;矢量频谱分析&#xff09;后会出现以下界面&#xff1a; 当然这是因为频谱仪的输入有信号才显示如下&#xff1a; 否则就显示频谱仪的噪…

初识C++ · 类和对象(中)(2)

前言&#xff1a;上篇文章已经介绍了6个默认成员函数中的3个函数&#xff0c;分别是构造函数&#xff0c;析构函数&#xff0c;拷贝构造函数&#xff0c;本文介绍的是后三个&#xff0c;赋值运算符重载&#xff0c;const成员函数&#xff0c;取地址操纵符重载。 目录​​​​​…

通过使用XShell工具、Nginx环境实现服务器项目构建与发布

前言&#xff1a; 在信息化和数字化的今天&#xff0c;网站和应用的构建与发布已成为企业发展的重要一环。为了确保项目的顺利上线和稳定运行&#xff0c;选择合适的工具和环境至关重要。本文将详细介绍如何通过XShell工具以及Nginx环境来实现服务器项目的构建与发布&#xff0…