【Go系列】 array、slice 和 map

承上启下

        我们上一篇文章中介绍了if和for,这不得练习下,让我们一起来实践一下如何使用 continue 语句来计算100以内的偶数之和。在我们编写代码的过程中,continue 语句将会帮助我们跳过某些不需要的迭代,比如在这个例子中,我们会跳过所有的奇数。

sum := 0
for i := 1; i < 100; i++{if i & 1 == 0 {continue}sum += i
}fmt.Println("the sum is",sum)

开始学习

在编程中,我们经常需要处理一组相同类型的元素,这些元素集合在 Go 语言中有特定的数据结构来表示。今天,我将为大家详细介绍 Go 中的几种集合类型:数组(array)、切片(slice)和映射(map)。

数组

首先,让我们从数组开始。数组是 Go 中最基础的数据结构,它是一组具有相同类型元素的固定长度的序列。数组一旦声明,其长度就不可改变。数组的声明和初始化非常简单,

声明数组

声明数组时,你需要指定数组类型和数组长度。以下是数组的声明方式:

var arrayName [arrayLength]elementType

例如,声明一个长度为 5 的整型数组:

var numbers [5]int
初始化数组

你可以通过多种方式初始化数组:

  • 使用字面量初始化:
var numbers = [5]int{1, 2, 3, 4, 5}
  • 使用 := 简短声明:
numbers := [5]int{1, 2, 3, 4, 5}
  • 自动推断数组长度:
numbers := [...]int{1, 2, 3, 4, 5}
  • 指定索引初始化:
numbers := [5]int{0: 1, 4: 5}

数组的特点

  • 固定长度:数组的长度在声明时确定,之后不能更改。
  • 相同类型元素:数组只能包含相同类型的元素。
  • 内存连续分配:数组元素在内存中是连续分配的,这使得访问数组元素非常高效。

访问数组元素

你可以通过索引来访问数组中的元素,索引从 0 开始:

value := numbers[2] // 获取索引为 2 的元素

遍历数组

你可以使用 for 循环来遍历数组中的所有元素:

for i, value := range numbers {fmt.Printf("Index: %d, Value: %d\n", i, value)
}

数组的长度

你可以使用内置的 len 函数来获取数组的长度:

length := len(numbers)

数组的零值

如果数组没有显式初始化,它的元素将被自动设置为其类型的零值。例如,整型数组的零值是 0:

var numbers [5]int // 所有元素都是 0

多维数组

Go 语言也支持多维数组。以下是声明和初始化一个 2x3 的整型数组的示例:

var matrix [2][3]int
matrix = [2][3]int{{1, 2, 3}, {4, 5, 6}}

数组的局限性

由于数组的长度是固定的,这在某些情况下可能不太灵活。如果需要一个可变长度的集合,可以使用切片(slice)。

切片

接下来是切片,它是一种更为灵活的内置类型,可以看作是动态数组。切片的长度是可变的,它基于数组创建,提供了更多的便利性。下面是如何声明和初始化一个切片:

s := make([]int, 3)      // 创建一个长度为3的整型切片
s[0] = 1                // 切片元素赋值
s[1] = 2
s[2] = 3
s = append(s, 4)        // 向切片追加元素

在 Go 语言中,数组和切片虽然都用于存储一系列相同类型的元素,但它们在内存分配、大小可变性、以及使用方式上存在显著的不同。以下是数组和切片的主要区别:

大小可变性

  • 数组:数组的大小在声明时确定,并且之后不可更改。数组的大小是其类型的一部分,因此 [3]int 和 [4]int 是不同的类型。
  • 切片:切片是动态的,可以在运行时增长或缩小。切片的大小不是其类型的一部分,因此 []int 是所有整型切片的共同类型。

内存分配

  • 数组:数组是值类型,当数组作为函数参数传递时,会传递其值的副本。这意味着对函数内部数组的修改不会影响原始数组。
  • 切片:切片是引用类型,它内部包含一个指向底层数组的指针、切片的长度以及容量。当切片作为函数参数传递时,传递的是指针的副本,因此函数内部对切片的修改会影响原始切片。

初始化

  • 数组:初始化数组时,必须指定其大小,并且可以立即赋予元素值。
  • 切片:切片可以通过字面量、make 函数或从数组中切片来初始化,不需要指定大小。

示例代码

以下是数组和切片的初始化示例:

// 数组
var arr [3]int = [3]int{1, 2, 3}// 切片
var slice []int = []int{1, 2, 3}
// 或者使用 make 函数
slice := make([]int, 3)

功能差异

  • 数组:由于大小固定,数组在编译时就知道其大小,这使得数组在栈上分配内存是可能的,并且访问数组元素的时间复杂度是 O(1)。
  • 切片:切片提供了更多灵活性,可以通过 append 函数添加元素,或者通过切片操作来获取子切片。切片的底层数组可能是在堆上分配的,访问切片元素的时间复杂度也是 O(1),但是 append 可能会导致底层数组的重新分配,这通常是 O(n) 操作。

映射

最后,我们来看看映射。映射是 Go 中的关联数组,它将键映射到值。映射的键可以是任何相等性操作符支持的类型,如整数、浮点数、字符串、指针、接口(只要接口内部包含的值是可比较的)、结构体和数组。映射的值可以是任何类型。

声明和初始化

声明 map

声明一个 map 的语法如下:

var mapName map[keyType]valueType

例如,声明一个键为字符串类型,值为整型类型的 map:

var scores map[string]int
初始化 map

在声明 map 之后,你需要通过 make 函数来初始化它,这样才能使用它:

scores = make(map[string]int)

或者,你可以使用简短声明并初始化:

scores := make(map[string]int)

也可以在声明的同时使用字面量进行初始化:

scores := map[string]int{"alice":  90,"bob":    85,"charlie": 88,
}

map 的特点

  • 键的唯一性:在 map 中,每个键都是唯一的,如果尝试插入一个已经存在的键,它会更新该键对应的值。
  • 无序:map 是无序的,每次迭代 map 时,元素的顺序可能会不同。
  • 动态大小:map 的大小是动态的,你可以根据需要添加或删除键值对。
  • 引用类型:map 是引用类型,当你将 map 传递给函数时,实际上传递的是指向底层数据结构的指针。

操作 map

添加元素
scores["alice"] = 90
获取元素
value := scores["alice"]

如果键不存在,将返回该值类型的零值。

检查键是否存在

可以使用逗号-ok idiom 来检查键是否存在于 map 中:

value, exists := scores["alice"]
if exists {// 键存在
} else {// 键不存在
}
删除元素

使用 delete 函数可以从 map 中删除一个键值对:

delete(scores, "alice")

如果键不存在,delete 函数什么也不做。

遍历 map

使用 for 循环可以遍历 map 中的所有键值对:

for key, value := range scores {fmt.Printf("%s: %d\n", key, value)
}

map 的零值

map 的零值是 nil。一个 nil map 没有底层数据结构,并且不能添加元素。在向 map 添加元素之前,你必须使用 make 初始化它。

map 的长度

可以使用内置的 len 函数来获取 map 中键值对的数量:

length := len(scores)

map 的键类型

map 的键可以是任何可以比较的类型,比如整数、浮点数、字符串、指针、接口(只要接口内部包含的值是可比较的)、结构体、数组等。切片、map 和函数不能用作 map 的键,因为这些类型不支持相等性比较。

易错点

在 Go 语言中,数组、切片和 map 是三种常用的数据结构,它们各自有不同的特点和注意事项。以下是一些在使用它们时需要注意的点:

数组(Array)

  • 避免使用过大的数组,因为它们会占用大量栈空间,可能导致栈溢出。
  • 当需要固定大小的数据集合时使用数组。

切片(Slice)

  • 切片扩容时可能会发生内存重新分配,应尽量预分配足够容量以避免频繁扩容。
  • 避免使用过大的切片,因为它们可能会占用大量堆空间。
  • 注意切片的零值是 nil,在使用之前需要初始化。

map(映射)

  • map 的零值是 nilnil map 不能用于存储键值对,使用前必须初始化。
  • 在并发环境中,对 map 的读写操作不是线程安全的,需要使用互斥锁或其他同步机制来保护。
  • 使用 delete 删除不存在的键不会产生错误,但检查键是否存在是安全的做法。

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

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

相关文章

欣奇随机美图源码

欣赏养眼美图让人心情愉悦 新增正能量进站引导首页 上传文件解压即可用有手就行 美图输出接口自判断版 http://mt.xqia.net/api.php http://mt.xqia.net/api.php?typejson 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89520368 更多资源下载&…

20240711每日消息队列-------------MQ消息的积压的折磨

目标 解决MQ消息的积压 背景 菜馆系统----------- 系统读取消息&#xff0c;处理业务逻辑&#xff0c;持久化订单和菜品数据&#xff0c;然后将其显示在菜品管理客户端上。 最初我们的用户基数很小&#xff0c;上线后的一段时间内&#xff0c;MQ消息通信还算顺利。 随着用户…

基于深度学习的视频内容分析

基于深度学习的视频内容分析是一种利用深度学习技术对视频数据进行处理和理解&#xff0c;以提取有用信息、识别对象和行为、检测事件和生成描述等的方法。这种技术在监控安全、视频搜索、自动驾驶、智能家居和娱乐等多个领域具有广泛应用。以下是关于这一领域的系统介绍&#…

java实现对多层json排序

1、概述 目的&#xff1a;对多层json排序&#xff0c;按字母的升序排序。实现方案&#xff1a;利用java中的TreeMap排序特性进行排序。 2、工具类 package com.ybw.util;import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject;import java.util.Map;…

(三)大模型/人工智能/机器学习/深度学习/NLP

一.模型 模型&#xff0c;简单来说&#xff0c;就是用来表示或解释某个事物、现象或系统的一种工具或框架。它可以是实体的&#xff0c;也可以是虚拟的&#xff0c;目的是为了帮助我们更好地理解和预测所描述的对象。在生活中&#xff0c;模型无处不在&#xff0c;它们以各种形…

R包:‘ggcharts好看线图包‘

介绍 ggcharts提供了一个高级{ggplot2}接口&#xff0c;用于创建通用图表。它的目标既简单又雄心勃勃:让您更快地从数据可视化的想法到实际的绘图。所以如何?通过处理大量的数据预处理&#xff0c;为您模糊{ggplot2}细节和绘图样式。生成的图是ggplot对象&#xff0c;可以使用…

蓝桥 7.11 dp

2.砝码称重 - 蓝桥云课 (lanqiao.cn) 思路 动态规划的核心思想是将问题分解成更小的子问题&#xff0c;并存储子问题的解&#xff0c;以避免重复计算 数组 dp[i][j] 表示使用前 i 个砝码可以称出的重量为 j 的数量 更新过程如下&#xff1a; 1.初始化&#xff1a;dp[0][0] …

java中关于反射与动态代理

java中关于反射与动态代理 java反射技术 1、什么是反射&#xff1f; Java反射说的是在运行状态中&#xff0c;对于任何一个类&#xff0c;我们都能够知道这个类有哪些方法和属性。对于任何一个对象&#xff0c;我们都能够对它的方法和属性进行调用。我们把这种动态获取对象信…

python:sympy 求解一元五次方程式

pip install sympy 或者 本人用的 anaconda 3 自带 sympy 在北大数学训练营&#xff0c;韦东奕 用卡丹公式 巧妙 求解一元五次方程式&#xff1a; \latex $x^510*x^320*x-4 0$ from sympy import *x symbols(x) expr x**5 10*x**3 20*x -4# 用卡丹公式 尝试化简 a sym…

鸿蒙开发工程师面试题-架构篇

1. 假如让你负责鸿蒙App架构设计&#xff0c;你会关注哪些方面&#xff1f; 分层架构设计&#xff1a; 将应用划分为产品定制层、基础特性层和公共能力层&#xff0c;以降低层间依赖性&#xff0c;提升代码可维护性。通过分层架构设计&#xff0c;进一步明确每层的职责和层间交…

【IOS】React Native之HelloWorld

RN搭建开发环境 rvm 安装3.2.2 brew install node18 brew install watchman# 使用nrm工具切换淘宝源 npx nrm use taobao# 如果之后需要切换回官方源可使用 npx nrm use npmnpm install -g yarnbrew install cocoapodsnpm uninstall -g react-native-cli react-native-communi…

<数据集>表情识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2504张 标注数量(xml文件个数)&#xff1a;2504 标注数量(txt文件个数)&#xff1a;2504 标注类别数&#xff1a;7 标注类别名称&#xff1a;[Neutral, Happy, Angry, Fear, Sad, surprised, Disguist] 序号类别名…

小白学webgl合集-import.meta.url 和 new URL() bug

为什么使用 import.meta.url 和 new URL() 动态路径解析&#xff1a; 在 ESM&#xff08;ECMAScript Modules&#xff09;环境中&#xff0c;import.meta.url 提供了当前模块的完整 URL。结合 new URL()&#xff0c;你可以基于这个 URL 动态解析其他资源的路径。这样可以确保路…

开始Linux之路(暑假提升)

人生得一知己足矣&#xff0c;斯世当以同怀视之。——鲁迅 Linux操作系统简单操作指令 1、ls指令2、pwd命令3、cd指令4、mkdir指令(重要)5、whoami命令6、创建一个普通用户7、重新认识指令8、which指令9、alias命令10、touch指令11、rmdir指令 及 rm指令(重要)12、man指令(重要…

Transformer——多头注意力机制(Pytorch)

1. 原理图 2. 代码 import torch import torch.nn as nnclass Multi_Head_Self_Attention(nn.Module):def __init__(self, embed_size, heads):super(Multi_Head_Self_Attention, self).__init__()self.embed_size embed_sizeself.heads headsself.head_dim embed_size //…

【VSCode】设置背景图片

1.下载background插件&#xff1a;拓展程序→background→install安装→设置&#xff1a; 2.点击在 settings.json 中编辑&#xff1a; 3.将settings.json文件中所有代码注释&#xff0c;添加以下代码&#xff1a; {// 是否开启背景图显示"background.enabled": t…

【Linux杂货铺】1.环境变量

1.环境变量基本概念 环境变量&#xff08; environment variables &#xff09;一般是指在操作系统中用来指定操作系统运行环境的一些参数。如&#xff1a;我们在编写 C / C &#xff0b;代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪…

【Go系列】 Go语言数据结构

承上启下 在上一次的思维碰撞中&#xff0c;我们的小试牛刀是一段温馨的代码小练习——将“Hello World”这个熟悉的问候&#xff0c;替换成了我们自己的名字。是的&#xff0c;你没听错&#xff0c;就是这么简单&#xff01;以我为例&#xff0c;我将“Hello World”轻轻一变&…

算法训练 | 图论Part8 | 拓扑排序、dijkstra(朴素版)

目录 117. 软件构建 拓扑排序法 47. 参加科学大会 dijkstra法 117. 软件构建 题目链接&#xff1a;117. 软件构建 文章讲解&#xff1a;代码随想录 拓扑排序法 代码一&#xff1a;拓扑排序 #include <iostream> #include <vector> #include <queue> …

什么是Web3D?国内有哪些公司可以做?

Web3D 是一种基于网页的三维立体虚拟现实技术。利用计算机图形学、图像处理、人机交互等技术&#xff0c;将现实世界中的物体、场景或概念以三维立体的方式呈现在网页里。Web3D 技术可以让用户在任何时间、任何地点&#xff0c;通过互联网与虚拟世界进行互动&#xff0c;获得身…