Golang 数组+切片+映射

数组

什么是数组

  • 数组是一种数据类型,属于值类型
  • 数组可以存放多个同一类型数据

数组定义

var 数组名 [数组大小]数据类型
var a [5]int

数组初始化的4种方式

var numArray01 [3]int = [3]int{1,2,3}
var numArray02 = [3]int{1,2,3}
var numArray03 = [...]int{1,2,3}  // 长度自行推导
var numArray04 = [3]{0:1,2:3} // 指定下标

数组遍历

// 方法1:
for i := 0; i < len(arr); i++ {
    fmt.Println(arr[i])
}

// 方法2:
for index, value := range arr {
    fmt.Println(index, " ", value)
}

数组对比

  • 数组可以用 == 和 != 进行比较
  • 但不能用 > < >= <= 等符号

数组相互赋值

  • 当数据类型和数组长度相同时,两个数组之间可以相互赋值

数组注意事项

  • 数组一旦定义后,长度不能改变,且数组中每个元素都有数据类型对应的默认值

  • 可以通过数组名来获取数组第一个元素的地址,即 数组名 == &数组名[0] == 数组首地址

  • 数组中各个元素的地址间隔由数组类型决定,比如 int64 -> 相隔8,int32 -> 相隔4

  • 数组是值类型,作为参数时,是值传递,即在函数内修改数组,不会对原数组影响,除非使用指针

  • 不能将 [3]int 类型的数组传递给 [4]int 的参数,它们被认为是不同类型;但是 […]int{1,2,3} 可以传递给 [3]int 的参数

  • 对于指向数组的指针,仍然可以用[index]进行索值

    var arr [5]int{1,2,3,4,5}
    var p = &arr
    // p[3] == arr[3]
    

二维数组

  • 声明

    var 数组名 [大小][大小]类型
    
  • 赋值

    数组名[n][m] = 123
    
    没有赋值或初始化就是默认值
    
  • 初始化

    var 数组名 [大小][大小]类型 = [][大小][大小]类型{{初值},{初值},{初值}}
    var 数组名 [大小][大小]类型 = {{初值},{初值},{初值}}
    var 数组名 = [大小][大小]类型{{初值},{初值},{初值}}
    var 数组名 = [...][大小]类型{{初值},{初值},{初值}}
    
  • 使用

    fmr.Println(数组名[n][m]) 
    
  • 遍历

    // 方法1:
    for i := 0; i< len(arr); i++ {
        for j := 0; j < len(arr[i]); j++ {
            fmt.Println(arr[i][j])
        }
    }
    
    // 方法2:
    for i,v := range arr {
        for j,v2 := range v {
            fmt.Println(v2)
        }
    }
    
  • 示意图

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

切片

什么是切片

  • 切片是引用类型,指向一个结构体,结构体包括一个数组的指针,切片大小,切片容量
  • 切片的长度是可变的,因为切片底层是动态数组,所以切片的操作和数组很类似

定义切片

var 切片名 []类型
var s []int

切片初始化

// 如果没有给切片赋值,则是类型的默认值
// 如果切片没有初始化,也是可以使用的,这与 map 必须初始化后才能使用不同

// 方式1:直接初始化
var s []int = []int{1,3,5}

// 方式2:由已存在数组创建
var intArr [5]int = [...]int{1,2,3,4,5}
s := intArr[1:3] // [1,3)
// arr[0:end] 等价 arr[:end]
// arr[start:len(str)] 等价 arr[start:]
// arr[0:len(str)] 等价 arr[:]

// 方式3:通过 make 来创建切片
// 通过 make 方法创建的切片,其底层数组是 make 内部维护的,外部不可见
// 所以切片的值是默认值
var s []int = make([]int, 4) // 只指定了 length,则capacity == length
var s []int = make([]int, 4, 10) // []type, length, capacity 

切片遍历

var arr [5]int = [...]int{10,20,30,40,50}
slice := arr[0:3]

// 方式1
for i := 0; i < len(slice); i++ {
    fmt.Println(slice[i])
}

// 方式2
for i, v := range slice {
    fmt.Println(i, v)
}

切片追加元素

var slice []int = []int{1,2,3}
slice = append(slice,5,6,7) // 返回新的 slice 
slice = append(slice,slice) // 可以把slice追加给slice

切片append操作原理

  • 切片append操作本质就是对数组进行扩容
  • Go底层会创建一个新的数组newArr
  • 将slice原来的元素拷贝到新的数组newArr中
  • newArr是底层维护的,程序员不可见
  • 然后创建一个新的sliceNew,sliceNew的ptr指向newArr
  • 最后返回 sliceNew
  • 当切片容量少于等于1000时,以2倍扩容,当大于1000时,以1.25倍扩容

切片拷贝操作

copy(para1,para2) //para1 和 para2 都是切片类型,将para2的内容复制到para1

切片内存布局

  • 切片是引用类型,切片名变量存储的是一个结构体的地址,即切片名是结构体的指针

  • 结构体包含三个值:

    • 封装数组的地址

    • 切片的大小

    • 切片的容量

      type slice struct {
          ptr *[2]int
          length int
          capacity int
      }
      

切片和字符串

  • 字符串底层是 []byte,因此也可以切片

    str := "hello world"
    slice := str[0:5]
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 字符串是不可变的

    str[0] = 'z' // error
    
    // 正确
    var temp []byte = []byte(str) // 只能处理字母和数字,因为中文是3个字节
    temp[0] = 'z'               
    str = string(temp)
    
    // 如果想要处理中文,则转为rune即可
    var temp []rune = []rune(str)
    temp[0] = 'z'               
    str = string(temp)
    

基于原有切片定义新切片

slice := []int{1, 2, 3, 4, 5}
slice1 := slice[:]
slice2 := slice[0:]
slice3 := slice[:5]
  • 设置切片长度和容量一样的好处
让新切片的长度和容量一样,这样我们在追加操作的时候就会生成新的底层数组,和原有数组分离,就不会因为共用底层数组而引起奇怪问题,因为共用数组的时候修改内容,会影响多个切片

空切片和nil切片

nil切片: var slice []int
空切片:  slice := make([]int,0)

映射

映射类型声明的三种方式

  • 仅仅进行声明

    var 变量名 map[keyType]valueType
    
  • 声明时直接初始化

    var 变量名 map[string]int = make(map[string]int, 10) // 10可以省略
    var 变量名 map[string]int = make(map[string]int) // 10可以省略
    
  • 声明时直接赋值

    var 变量名 map[string]int = map[string]int{
        "one": 1,
        "two": 2,
    }
    

映射 key 和 value 的要求

  • key 必须支持 == 运算
    • 一般用 string 和 数值 ,还可以用 bool,指针,channel
    • 不能用 slice,map和function
  • value可以是string,数值,bool,struct,map 不能用slice,map和function

映射的赋值 [增,改]

  • m[“key”] = value
  • 当m中本身没有 key 时,会新增
  • 当m中本身有 key 时,会覆盖
  • 当空间不够时,会自动扩容

映射的删除 [删]

  • delete(m, “one”)
  • 当删除的 key 不存在时,既不操作也不报错
  • Go中没有方法可以一次性清除整个map,如果想,则可以遍历,或者让变量指向一个新的 map,让 gc 把原来那个删除了

映射的查找 [查]

  • val := m[“one”]
  • 访问不存在的 key 值,返回类型默认类型,而不报错
  • val, findRes := m[“one”]
  • 如果找到了 val 为 key 对应值,findRes为 false
  • 如果找不到 val 为 类型默认值 ,findRes为true

映射的遍历

  • 不能用 for 循环,因为映射是无序的

  • 需要使用 for-range 循环,其中 k 和 v 是拷贝的

    for k,v := range m {
        fmt.Printf("k=%v,v=%v",k,v)
    }
    
  • golang中的map是无序的,每次遍历的结果都可能不一样

映射的排序

  • golang中的map是无序的,每次遍历的结果都可能不一样

  • golang中没有专门的方法针对map的key进行排序

  • 如果想要对映射排序,则可以先拿出所有的key,将key进行排序,再取出value

    var keys []int
    
    for key, _ := range m {
        keys = append(keys, key)
    }
    
    sort.Ints(key)
    

映射注意事项

  • 声明是不会分配内存的,默认值为nil
  • 需要使用make来初始化,分配内存后才能使用,make就是给map分配空间
  • map的存储是无序的
  • 使用内建函数 len 可以获取映射中键值对的个数
  • 映射底层的数据结构是哈希表,所以无序
  • new函数对于map的作用:p := new(map[string]int),仅仅分配了字典类型本身(实际就是个指针包装)所需内存,并没有分配键值对存储的内存,因此无法正常使用

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

直接更新flowable数据库的流程定义信息的一种方法

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

servlet学校会场预约系统-计算机毕业设计源码72972

摘要 学校会场预约是学校管理中的重要环节&#xff0c;但传统的手工预约方式存在效率低下和信息不准确等问题。为了提高预约效率和减少管理成本&#xff0c;许多学校开始采用基于Servlet技术的会场预约系统。本论文旨在设计和实现一种高效的Servlet学校会场预约系统&#xff0c…

Apache Flink架构介绍

目录 一、Apache Flink架构组件栈 1.1 概述 1.2 架构图 1.3 架构分层组件说明 1.3.1 物理部署层 1.3.2 Runtime 核心层 1.3.3 API & Libraries层 二、Flink运行时架构 2.1 概述 2.2 架构图 2.3 架构角色和组件 2.3.1 Flink Clients客户端 2.3.2 JobManager 2.…

微信小程序留言板1

wxml&#xff1a; <view class"view2"> <text class"test1">留言&#xff1a;</text><input type"text" class"input1" bindinput"ipt"/><button class"btn" bindtap"btn"…

《简历宝典》01 - 一文带你学会如何写一份糟糕透顶的简历

我们每个人几乎都会面对找工作这件事&#xff0c;而找工作或者说求职首先就是要写一份简历。今天狗哥将以一个不同的视角带你写一份无与伦比&#xff0c;糟糕透顶的求职简历&#xff0c;说实话&#xff0c;其实几年前&#xff0c;我就是这么写的。 目录 1. 文件名 2. 基本信…

C++ thread线程库

thread库 std::thread 是 C 标准库中的一个类&#xff0c;用于管理和控制单个执行线程。线程允许程序并行执行多个函数&#xff0c;从而提高性能和响应速度。std::thread 类提供了一种便捷的方式来创建和操作线程。 1、用途 并行执行任务&#xff1a; 通过 std::thread&…

滚动表格(vue版本)【已验证可正常运行】

演示图 注&#xff1a;以下代码来自于GPT4o&#xff1a;国内官方直连GPT4o 代码 <template><div><div class"alarmList-child" ref"alarmList" mouseenter.stop"autoRoll(1)" mouseleave.stop"autoRoll()"><div…

相机光学(二十四)——CRA角度

CRA角度 0.参考资料1.什么是CRA角度2.为什么 CRA 会导致luma shading3.为什么 CRA 会导致color shading4.CRA相差过大的具体表现5.CRA Matching6.怎样选择sensor的CRA 0.参考资料 1.芯片CRA角度与镜头的匹配关系&#xff08;一&#xff09;   2.芯片CRA角度与镜头选型的匹配关…

记录一次麒麟V10 安装sysbench各种报错(关于MySQL)处理过程

sysbench手工下载&#xff1a; https://github.com/akopytov/sysbench 下载.zip文件&#xff0c;上传到服务器上 解压、安装&#xff1a; unzip sysbench-master.zipcd sysbench-master/sh autogen.sh./configure 报错&#xff1a;没有mysql驱动 configure: error: mysql_c…

MySQL数据库-Windows部署MySQL环境

Windows部署MySQL环境​​​​​​ 一、下载mysql数据库 进入MySQL官方网站&#xff08;MySQL :: MySQL DownloadsMySQL&#xff09;&#xff0c;随后按如下红框方式操作&#xff1a; ​ ​ ​ ​ 这里选择的是离线安装&#xff0c;第一个是在线安装 下载好安装包后开始…

iPad手写笔哪款比较好?2024五款爆火iPad电容笔推荐!新手必看!

在iPad等触控设备日益普及的今天&#xff0c;手写笔作为提升生产力和创意表达的重要工具&#xff0c;正受到越来越多用户的青睐。然而&#xff0c;随着市场需求的激增&#xff0c;市面上电容笔品牌与型号繁多&#xff0c;跟风购买往往容易遭遇“踩雷”情况。因此&#xff0c;作…

【Linux】查找命令——which,type,find,whereis,locate

命令与文件的查找 文件的查找可就厉害了&#xff0c;因为我们常常需要知道哪个文件放在哪里&#xff0c;才能够对该文件进行一些修改或维护等操作。 有时候某些软件配置文件的文件名是不变的&#xff0c;但是各Linux发行版放置的目录则不同。 此时就要利用一些查找命令将该配…

iPad电容笔什么牌子好?2024最值得买的五款高性价比电容笔推荐!

现在平板和电容笔在一定程度上可以替代传统的笔和纸&#xff0c;不仅减少纸张浪费&#xff0c;还可以导入教材和习题册。只需携带它们就无需携带厚重的书本&#xff0c;这种环保、便捷、方便的特点吸引了越来越多的用户。但电容笔品牌的不断涌现&#xff0c;也让用户更加难以抉…

Wormhole Filters: Caching Your Hash on Persistent Memory——泛读笔记

EuroSys 2024 Paper 论文阅读笔记整理 问题 近似成员关系查询&#xff08;AMQ&#xff09;数据结构可以高效地近似确定元素是否在集合中&#xff0c;例如Bloom滤波器[10]、cuckoo滤波器[23]、quotient滤波器[8]及其变体。但AMQ数据结构的内存消耗随着数据规模的增长而快速增长…

管易云和金蝶云星空单据接口对接

管易云和金蝶云星空单据接口对接 数据源系统:金蝶云星空 金蝶K/3Cloud在总结百万家客户管理最佳实践的基础上&#xff0c;提供了标准的管理模式&#xff1b;通过标准的业务架构&#xff1a;多会计准则、多币别、多地点、多组织、多税制应用框架等&#xff0c;有效支持企业的运营…

400G SR4和800G SR8光模块在AI集群中的应用

人工智能&#xff08;AI&#xff09;技术的快速发展下&#xff0c;AI集群的计算能力和数据传输需求不断提升。为了满足这一需求&#xff0c;光模块技术也在不断进步。高速率光模块作为新一代高速光通信解决方案&#xff0c;正在逐步应用于AI集群中&#xff0c;为其提供更高效、…

【带你全面了解 RAG,深入探讨其核心范式、关键技术及未来趋势】

文末有福利&#xff01; 大型语言模型&#xff08;LLMs&#xff09;已经成为我们生活和工作的一部分&#xff0c;它们以惊人的多功能性和智能化改变了我们与信息的互动方式。 然而&#xff0c;尽管它们的能力令人印象深刻&#xff0c;但它们并非无懈可击。这些模型可能会产生…

google::protobuf命名空间下常用的C++ API----message.h

#include <google/protobuf/message.h> namespace google::protobuf 假设您有一个消息定义为: message Foo {optional string text 1;repeated int32 numbers 2; } 然后&#xff0c;如果你使用 protocol编译器从上面的定义生成一个类&#xff0c;你可以这样使用它: …

[C++][设计模式][访问器]详细讲解

目录 1.动机2.模式定义3.要点总结4.代码感受1.代码一2.代码二 1.动机 在软件构件过程中&#xff0c;由于需求的变化&#xff0c;某些类层次结构中常常需要增加新的行为(方法)&#xff0c;如果直接在基类中做这样的更改&#xff0c; 将会给子类带来很繁重的变更负担&#xff0c…

快手矩阵管理系统:开启短视频营销的智能时代

在短视频内容营销的浪潮中&#xff0c;快手矩阵管理系统以其独特的优势和功能&#xff0c;成为品牌和个人创作者不可或缺的工具。本文将详细解析快手矩阵管理系统的核心功能&#xff0c;探讨它如何帮助用户高效管理多平台、多账号的内容发布和互动。 快手矩阵管理系统概述 快…
最新文章