Golang基础2-Array、Slice、Map

news2025/1/15 16:47:56

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 main

import "fmt"

// 定义数组测试
func Test1() {
    var a [5]int
    b := [...]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 main

import "fmt"

func main() {

    //var arr1 [5]int

    //声明切片,注意与数组对比
    var s1 []int
    if 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 main

import "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] = 100
    fmt.Println(arr)
    //实际操作底层数组
    fmt.Println(x, y)
    //    [0 100 2 3 4 5]
    //    [0 100 2 3 4 5] [100 2]

    fmt.Println()

    x[2] = 200
    fmt.Println(arr)
    //实际操作底层数组
    fmt.Println(x, y)
}

追加元素append demo

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

老数组

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

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

package main

import "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] = 200
    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)
}

新数组:

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

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

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

新数组扩容demo

package main

import "fmt"

// 了解分配策略
func main() {
    //初始化slice
    slice := []int{0}
    c := cap(slice)
    num := 0 //计数,扩容次数
    for i := 0; i < 1024; i++ {
        //添加前cap
        preArr := &slice[0]
        preSlice := &slice
        slice = 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 = n
            num++
        }
    }
    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 main

import (
    "container/list"
    "fmt"
)

func main() {
    var mylist = list.List{}

    mylist.PushBack(123)
    mylist.PushBack(456)
    mylist.PushBack(789)
    fmt.Println(mylist)

    // 遍历list
    for 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 main

import "fmt"

// 全局初始化
var map1 map[int]string

func main() {
    //等价
    //可以声明时初始化
    //scoreMap := map[string]int{}
    
    //可以声明初始化空间
    scoreMap := make(map[string]int, 0)
    scoreMap["张三"] = 100
    scoreMap["赵六"] = 10
    scoreMap["李四"]=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,value
    delete(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.coloradmin.cn/o/1628709.html

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

相关文章

知识图谱嵌入领域的重要研究:编辑基于语言模型的知识图谱嵌入

今天&#xff0c;向大家介绍一篇在知识图谱嵌入领域具有重要意义的研究论文——Editing Language Model-based Knowledge Graph Embeddings。这项工作由浙江大学和腾讯公司的研究人员联合完成&#xff0c;为我们在动态更新知识图谱嵌入方面提供了新的视角和方法。 研究背景 在…

go设计模式之工厂方法模式

工厂方法模式 什么是工厂方法模式 工厂方法模式是一种创建型设计模式&#xff0c;它定义了一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化推迟到其子类。 这个接口就是工厂接口&#xff0c;子类就是具体工厂类&#xff0c;而需要创…

盛水最多的容器 ---- 双指针

题目链接 题目: 分析: 最大容积 即使就是最大面积, 长为下标之差, 宽为两下标对应值的最小值解法一: 暴力枚举: 将每两个数之间的面积都求出来, 找最大值, 时间复杂度较高解法二: 假设我们的数组是[6, 2, 5, 4], 我们先假设最左边和最右边, 即6 和 4 之间是最大面积长a*宽b此…

便携式应急指挥箱规格参数

概况: 微缩型的无线视频音频传输的机动挥所。体积小、重量轻、公配电方便、携带便携、功能齐全。可进行单兵作战&#xff0c;通过此无线音频视频传输的指挥箱能完成现场图像、语音、数据的采集等功能&#xff0c;可以通过5G/4G/WIFI等多种无线网络完成传输的需求&#xff0c;或…

和鲸科技出席第五届空间数据智能学术会议,执行总裁殷自强受邀发表主题报告

4月26日&#xff0c;由 ACM SIGSPATIAL 中国分会、ACM SIGMOD 中国分会主办的第五届空间数据智能学术会议&#xff08;SpatialDI 2024&#xff0c;下简称“会议”&#xff09;在南京盛大开幕。本次会议特邀李清泉院士、周成虎院士、丛高教授、谢炯博士、张雪英教授等国内外知名…

流量网关与服务网关的区别:(面试题,掌握)

流量网关&#xff1a;&#xff08;如Nignx&#xff0c;OpenResty&#xff0c;Kong&#xff09;是指提供全局性的、与后端业务应用无关的策略&#xff0c;例如 HTTPS证书认证、Web防火墙、全局流量监控&#xff0c;黑白名单等。 服务网关&#xff1a;&#xff08;如Spring Clou…

通义灵码-IDEA的使用教程

通义灵码-IDEA的使用教程 1、通义灵码是什么&#xff1f; 通义灵码&#xff0c;是阿里云出品的一款基于通义大模型的智能编码辅助工具&#xff0c;提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研发智能问答、异常报错排查等能力&#…

受尽折磨的ai剪辑视频心酸之路

因为公司需要剪辑好多视频~我每天不断手动剪啊剪啊手都剪麻 有天老板跟我说了句人家好多ai剪辑你能不能搞到一个&#xff0c;多少钱你在说。 我心想这不是我的强项么&#xff1f;白嫖界的天花板&#xff0c;我就拦下了这个活~于是我上班不是在找软件就是在逛论坛路上&#xff0…

【漏洞复现】润乾报表InputServlet13文件读取漏洞

漏洞描述&#xff1a; 润乾报表是一款功能全面且性能卓越的报表产品。它专注于企业级BI产品的研发和推广&#xff0c;通过提供丰富的报表功能和高效的开发工具&#xff0c;帮助用户提升图表的开发效率&#xff0c;节省成本。 润乾报表InputServlet13接口存在文件读取漏洞&…

数据结构 - 链表详解一 - 链表的介绍

一. 为什么要学习链表 我们已经学习了顺序表了&#xff0c;在学习的时候发现顺序表的功能很多&#xff0c;所以我们为什么还要学习链表呢&#xff0c;学习链表有什么用吗&#xff1f; 下面我将通过几个方面去研究一下 1. 动态数据操作 顺序表&#xff08;如数组&#xff09;通…

回溯-单词搜索

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或垂直相…

力扣刷题总结——栈和队列

刷完栈和队列&#xff0c;对STL的内容有了更加深刻的认识。 STL中栈往往不被归类为容器&#xff0c;而被归类为container adapter&#xff08;容器适配器&#xff09; 栈的内部结构&#xff0c;栈的底层实现可以是 vector&#xff0c;deque&#xff0c;list 都是可以的&#xf…

ANSYS WB DesignModeler 概述

Workbench 在进行有限元分析之前&#xff0c;一般需要创建或导入模型。创建模型时一般会用到 DesignModeler 组件&#xff0c;在该组件中可以进行2D和3D模型的创建。 本章主要讲述 DesignModeler 的基础操作,包括启动、图形界面、图形选择和右键快捷菜单。 1.启动 DesignModel…

【数字电路与系统】【北京航空航天大学】实验:时序逻辑设计——三色灯开关(二)、需求分析和系统设计

本次实验&#xff08;一&#xff09;见博客&#xff1a;【数字电路与系统】【北京航空航天大学】实验&#xff1a;时序逻辑设计——三色灯开关&#xff08;一&#xff09;、实验指导书 说明&#xff1a;本次实验的代码使用verilog编写&#xff0c;文章中为阅读方便&#xff0c…

OGG extract进程占据大量虚拟内存导致服务器内存异常增长分析

现象 oracle服务器一节点内存&#xff0c;一个月来持续升高&#xff0c;近一月上涨10%左右。 问题分析 OS内存使用情况 使用内存最大的10个进程如下&#xff0c;PID为279417占用最大的内存。 查询279417&#xff0c;发现是ogg相关进程。 发现ogg的extract进程占用了大量的虚拟内…

Lagent AgentLego 智能体应用搭建-笔记六

本次课程由Lagent&AgentLego 核心贡献者樊奇老师讲解【Lagent & AgentLego 智能体应用搭建】课程 课程视频&#xff1a;https://www.bilibili.com/video/BV1Xt4217728/ 课程文档&#xff1a;https://github.com/InternLM/Tutorial/tree/camp2/agent 大语言模型的局限…

E4980A是德科技E4980A精密LCR表

181/2461/8938产品概述&#xff1a; Keysight E4980A 精密 LCR 表为各种元件测量提供了精度、速度和多功能性的最佳组合。E4980A 在低阻抗和高阻抗范围内提供快速测量速度和出色的性能&#xff0c;是元件和材料的一般研发和制造测试的终极工具。LAN、USB 和 GPIB PC 连接可提高…

Openharmony - 设备异常关机Power Down问题分析

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 1.问题描述1.1出现power down的原因1.1.1硬件故障或信号1.1.2软件错误或系统崩溃2.抓日志信息2.1.抓日志方法2.2.问题初步分析3.问题排…

前后端分离实践:使用 React 和 Express 搭建完整登录注册流程

文章目录 概要整体架构流程技术名词解释ReactExpressReact RouterAnt Design 技术细节前端设计后端逻辑数据交互 小结 概要 本项目是一个基于React和Express的简单登录注册系统。通过前后端分离的方式&#xff0c;实现了用户的注册、登录和查看用户列表等功能。前端使用React框…

学习通刷课免费,成绩又高的方法(超详细)

文章目录 概要整体架构流程 概要 我们在大学的时候有好多课程都是线上的水课&#xff0c;这时我们需要刷课又不想花钱怎么办&#xff0c;这篇文章推荐三个脚本配合使用&#xff0c;成绩还不错亲试&#xff1b; 整体架构流程 1.我们先找到浏览器的扩展程序 2.点击获取扩展 …