【Hello Go】Go语言复合类型

复合类型

    • 分类
    • 指针
      • 基本操作
      • new函数
      • 指针作为函数的参数
    • 数组
      • 概述
      • 操作数据
      • 数组初始化
      • 数组比较
      • 在函数之间传递数组
    • slice
      • 概述
      • 切片的创建和初始化
      • 切片操作
      • 切片和底层数组关系
      • 内建函数
        • append
        • copy
      • 切片作为函数传参
    • map
      • 概述
      • 创建和初始化
      • 常用操作
        • 赋值
        • 遍历
      • 删除
      • map作函数参数
    • 结构体
      • 结构体类型
      • 结构体初始化
        • 普通变量
        • 指针变量
      • 结构体成员的使用
    • 结构体的比较
    • 结构体作为函数参数
      • 可见性

分类

复合类型的分类如下图

在这里插入图片描述

需要注意的是 在Go语言中 空的表示是用 nil 而不是 nullptr 或者是 NULL

指针

指针是一个代表着某个内存地址的值 该内存地址往往是内存中存储着另一个变量的值的起始位置

Go语言对于指针的支持介于Java和C++之间

它既没有像Java哪有取消了代码对指针直接操作的能力

也避免了C++对于指针滥用而造成的安全和可靠性问题

基本操作

Go语言虽然保留了指针 但是和其他编程语言不同的是

  • 默认值是nil 没有NULL 常量
  • 操作符是 & 取地址 * 通过指针直接访问对象 (这一点和C++相同)
  • 不支持指针运算 不支持->运算符 直接使用 “.” 访问目标成员

new函数

表达式new(T)将会创建一个T类型的匿名变量 我们可以使用一个T*的指针来接受结果

之后使用指针的各种操作进行访问修改即可

需要注意的是 我们无需关心new出来对象的声明周期 Go元的内存管理系统会帮我们打理一切

指针作为函数的参数

指针作为函数的参数使用和C++并无过多区别 这里就不在赘述

数组

概述

数组指的是一系列同一类型数据的集合

数组中包含的每个数据被称为数组元素 一个数组包含的元素个数被称为数组长度

注意! 和C语言一样 Go语言不支持变长数组 所以说数组的长度必须是一个常量

像是下面的写法就会报错

var n int = 10 
var arr [n]int  // 不能这么写 会报错

操作数据

数组的每个元素可以通过索引下标来访问 索引下标的范围是从0开始到数组长度减1的位置

这里有几个内置函数我们可以使用

  • len 返回数组的长度
  • cap 返回元素的数量

数组初始化

我们有下面几种初始化数组的方式

列表初始化

a := [3]int{1 , 2, 3}

通过初始化来确定数组长度

b := [...]int{1 , 2, 3}

通过索引号初始化元素 未初始化元素值为0

C := [5]int{2 : 100 , 4 : 200}

当然Go语言也支持多维数组的开辟 规则类似于C语言

我们可以自动推导行的大小 不能自动推导列的大小


数组比较

值得一提的是 Go语言中的数组可以使用 == 或者是 != 来进行比较

它会返回给我们一个bool类型 我们可以在进行数组校验的时候使用

在函数之间传递数组

在Go语言中并没有引用传参这种说法 所以说要想传递一个函数 我们只能通过传值和传指针的方式

slice

概述

数组的长度在定义之后无法再次修改 数组是值类型 每次传递都将会产生一个副本

显然这种数据结构无法满足开发者的真实需求 Go语言提供了数组切片(slice)来弥补数组的不足

切片并不是数组或数组指针 它通过内部指针和相关属性引用数组片段 以实现变长方案

slice并不是真正意义上的动态数组 而是一个引用类型 slice总是指向一个底层array slice的声明也可以像array一样 不需要长度

如下图
在这里插入图片描述

切片的创建和初始化

slice和数组的区别就是

  • 声明数组时 方括号内写明了数组的长度或者 … 来自动计算长度
  • 声明切片时方括号内没有任何的字符
s5 := []int{1, 2, 3} //创建切片并初始化

切片操作

切片的相关操作如下

在这里插入图片描述

演示结果如下
在这里插入图片描述

这里简单介绍下切片操作的规则

  • low表示从哪里开始
  • high表示到哪里结束
  • 最后的max表示容量 如果说指定了多少 那就是多少 如果没指定则用总容量减去起始位置

切片和底层数组关系

其实我们一开始介绍的时候就说过了 切片和底层数组之间是引用的关系

所以说如果我们修改切片的值 那么底层数组的值也会被改变的

内建函数

append

append函数的是想 slice 尾部添加数据 并且会返回一个新的slice对象

var s1 []int //创建 nil 切换
//s1 := make([]int, 0)
s1 = append(s1, 1) //追加 1 个元素
s1 = append(s1, 2, 3) //追加 2 个元素
s1 = append(s1, 4, 5, 6) //追加 3 个元素
fmt.Println(s1) //[1 2 3 4 5 6]
s2 := make([]int, 5)
s2 = append(s2, 6)
fmt.Println(s2) //[0 0 0 0 0 6]
s3 := []int{1, 2, 3}
s3 = append(s3, 4, 5)
fmt.Println(s3)//[1 2 3 4 5]

这里有一个问题是 切片的容量是有限的 万一有效数据超过容量了 此时应该怎么办呢

答案是切片会自动扩容 通常会以2倍的容量重新分配底层数组 并赋值原来的数据

copy

函数copy可以在两个slice之间复制数据 复制长度以len小的为准 两个slice可指向同一底层数组

  data := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}s1 := data[8:] //{8, 9}s2 := data[:5] //{0, 1, 2, 3, 4}copy(s2, s1) // dst:s2, src:s1fmt.Println(s2) //[8 9 2 3 4]fmt.Println(data) //[8 9 2 3 4 5 6 7 8 9]

这里需要注意的是复制源和目的地址的问题 是将后面的一个切片赋值道前面

切片作为函数传参

如果我们此时修改切片内部的值 那么此时外部切片的值也会改变

但是如果我们在函数内部将切片扩容了 那么此时就算我们在函数内部修改了切片 外部的切片也不会改变

map

概述

Go语言中的map是一种内置的数据结构 它是一个 无序 的key – value集合

在这里插入图片描述

map的格式为

map[keyType]valueType

在一个map里所有的建都是唯一的 而且必须是支持 == 和 !=操作的

切片 函数以及包含切片的结构类型 由于这些类型具有引用语义 不能作为映射的建 使用这些类型会造成编译错误

但是map的值可以是任意类型

需要注意的是 map是无序的 我们无法决定它的返回顺序 所以说每次打印的结果都有可能不同

其实看到这里我们就应该明白了 Go语言中map的底层使用了哈希表而不是红黑树

创建和初始化

创建方式如下

var m1 map[int]string {}       

此时我们创建了一个空的map

初始化方式如下

m2 := map[int]string {1 : "mike"  , 2 : "yoyo"}

常用操作

赋值

我们可以使用 [] 来对map进行修改和赋值

它的逻辑可以参考我直接写的这篇博客

方括号运算符详解

遍历

map的遍历方式有两种

  • 我们可以直接通过range获取key 和 value 之后打印即可
  • 我们可以只获取下标 然后通过下标访问额度方式来获取值

如果我们想要判断某个key对应的value是否存在的话 我们可以像下面这么做

  value , ok := m2[3]    fmt.Println(value , ok) // 如果ok是true则存在 如果是false则不存在                                   

删除

我们可以使用delete函数来进行删除

具体用法如下

delete(map, key值)

map作函数参数

在函数之间传递map的时候并不会制造出该映射的一个副本 不是值传递 而是引用传递

到这里我们总结下 回顾之前复合类型的分类图

在这里插入图片描述

我们可以发现 只有slice 和 map传递的时候是使用了引用类型 这一点比较奇怪 我们记住即可

结构体

结构体类型

我们单一的结构没办法描述一个复杂的对象 比如说学生 一个学生要有学号 姓名 年龄 地址等属性

但是如果我们一个个定义的话比较繁琐 虽然单独定义以上的变量比较繁琐 数据不便于管理

在这里插入图片描述

结构体初始化

普通变量

下面就是我们结构体中定义普通变量的方式

type  Student Struct {id int name stringaddress string
} 

对于普通变量我们有两种初始化方式

  1. 全部初始化 这种初始化必须要按照顺序来
type  Student Struct {id int name stringaddress string
} 
  1. 指定初始化某个成员 没有初始化的成员为零值

像我们下面的代码

	// 部分初始化s2 := Student{id : 2}
指针变量

其实指针变量的初始化和普通变量差别并不大 只是语法上有些许的变化

具体的代码如下

	// 此时s3就是一个指针 s3 := &Student{ 2 , "lili" , "addd"}

结构体成员的使用

在Go语言中 不管是普通变量 还是 指针变量 我们的访问方式都是不变的 所以说我们都可以使用 . 来访问并修改每个成员

结构体的比较

如果结构体的全部成员都是可以比较的 结构体是支持比较的 就像数组一样 但是只支持 == 和 != 不支持其他

结构体作为函数参数

结构体的传参很有意思 因为我们不管是普通成员还是指针都是使用 . 来访问并且修改成员变量的 这就导致 如果我们传递一个指针进去的话 就很类似于C++中的引用传参

所以说结构体作为函数传参有两种情况

  • 值传递
  • 引用传递 (底层还是传地址 指针)

可见性

Go语言对关键字的增加非常的吝啬 (这也可能是为了易学习性考虑)其中没有 private public 这些关键字

我们要让某个符号对其他包可见的话 需要将该符号定义以大写字母开头

比如说

type  Student Struct  //对其他包可见
type  student Struct  //对其他包不可见 因为首字母小写 

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

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

相关文章

近期问题笔记20231116

DMA的洛伦兹约束的来源 多拉格朗日乘子的拉格朗日对偶问题的次梯度搜索 鲁棒优化,only statistical CSI of the users-to-RIS channels H 2 , k \mathbf{H}_{2,k} H2,k​ is available 期望符号的去除, 阅读这篇论文 C.-K. Wen, S. Jin, and K.-K. …

导数...

导数定义: f ′ ( x 0 ) lim ⁡ x → x 0 f ( x ) − f ( x 0 ) x − x 0 f(x_0)\lim\limits_{x\rightarrow{x_0}}\frac{f(x)-f(x_0)}{x-x_0} f′(x0​)x→x0​lim​x−x0​f(x)−f(x0​)​ 罗尔定理:如果函数在[a,b]可导,并且f(a)f(b),那么[a,b]区间内一定有个导数是0 中值…

Python (十三) 输出

程序员的公众号:源1024,获取更多资料,无加密无套路! 最近整理了一波电子书籍资料,包含《Effective Java中文版 第2版》《深入JAVA虚拟机》,《重构改善既有代码设计》,《MySQL高性能-第3版》&…

基于Python+TensorFlow+Django的交通标志识别系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 随着交通网络的不断扩展和智能交通系统的发展,交通标志的自动识别变得愈发重要。本项目旨在利用Python编…

Redis--list列表

基础概念 元素必须是字符串类型列表头尾增删快,中间增删慢,增删元素是常态元素可以重复最多可以包含2^32 - 1个元素索引和python的列表一样 常用命令 - 增加数据 1.LPUSH key value1 value2 说明:从列表头部压入元素 返回:l…

矩阵转置

描述 输入N&#xff0c;和M&#xff0c;构建两个矩阵:A[N][M]&#xff0c;B[M][N]&#xff0c;M, N <50; 步骤1:输入M, N ; M, N <50; 步骤2:输入A[M][N]; 步骤3:计算:B[N][M]A[M][N]; 步骤4:输出:B [M] [N];这有几个测试组 输入 每个数字都是整数; 输入M, N; M, N <5…

利用SVD对图像进行压缩

利用SVD对图像进行压缩 使用SVD能够对数据进行降维&#xff0c;对图像进行SVD&#xff0c;降维之后然后重构数据&#xff0c;还原后的图像就是压缩后的图像。 SVD SVD进行图像压缩所依据的数学原理就是矩阵的近似表示&#xff1a; A m n ≈ U m k ∑ k k V k n T A_{m\…

基于晶体结构算法优化概率神经网络PNN的分类预测 - 附代码

基于晶体结构算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于晶体结构算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于晶体结构优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

Vue原型对象

原型对象 prototype 称为&#xff1a;显示的原型属性&#xff0c;用法&#xff1a;函数.prototype&#xff0c;例如&#xff1a;Vue.prototype __proto__称为&#xff1a;隐式的原型属性&#xff0c;用户&#xff1a;实例.proto&#xff0c;例如&#xff1a;vm.proto 不管如何 …

[Docker]八.Docker 容器跨主机通讯

一.跨主机通讯原理 在主机192.168.31.140上的docker0(172.17.0.0/16)中有一个容器mycentos( 172.17.0.2/16), 在主机192.168.31.81上的docker0(172.17.0.0/16)中有一个容器mycentos( 172.17.0.2/16),然后在主机192.168.31.140上ping主机192.168.31.81,发现ping不通要实现两个主…

vite构建项目不能使用require解决方案

在utils文件夹下创建一个getImgUrl.ts文件 /** vite的特殊性, 需要处理图片 */ export const require (imgPath: string) > {try {const handlePath imgPath.replace(, ..)console.log(handlePath::, imgPath)return new URL(handlePath, import.meta.url).href} catch (…

如何入驻抖音本地生活服务商,附上便捷流程!

抖音作为一款短视频社交媒体应用&#xff0c;已经成为全球范围内数以亿计的用户的首选。而在普及的同时&#xff0c;短视频领域也在不断拓展自身的业务领域&#xff0c;其中之一就是本地生活服务。继抖音本地生活服务之后支付宝、视频号也相继开展了本地生活服务&#xff0c;用…

Linux(5):Linux 磁盘与文件管理系统

认识 Linux 文件系统 磁盘的物理组成&#xff1a; 1.圆形的磁盘盘(主要记录数据的部分); 2.机械手臂&#xff0c;与在机械手臂上的磁盘读取头(可擦写磁盘盘上的数据)&#xff1b; 3.主轴马达&#xff0c;可以转动磁盘盘&#xff0c;让机械手臂的读取头在磁盘盘上读写数据。 4…

05_面对对象高级_抽象类

抽象类 1. 认识抽象类 在 Java 中有一个关键字叫&#xff1a;abstract &#xff0c;它的中文含义是"抽象"&#xff0c;可以用它来修饰类、成员方法。 abstract 修饰类&#xff0c;这个类就是抽象类。 abstract 修饰方法&#xff0c;这个方法就是抽象方法。 2. 注…

python接口自动化-参数关联

前言 我们用自动化发帖之后&#xff0c;要想接着对这篇帖子操作&#xff0c;那就需要用参数关联了&#xff0c;发帖之后会有一个帖子的id&#xff0c;获取到这个id&#xff0c;继续操作传这个帖子id就可以了 &#xff08;博客园的登录机制已经变了&#xff0c;不能用账号和密…

【算法设计实验三】动态规划解决01背包问题

请勿原模原样复制&#xff01; 01背包dp具体解释详见链接 ↓ 【算法5.1】背包问题 - 01背包 &#xff08;至多最大价值、至少最小价值&#xff09;_背包问题求最小价值_Roye_ack的博客-CSDN博客 关于如何求出最优物品选择方案&#xff1f; 先在递归求dp公式时&#xff0c;若…

Proteus下仿真AT89C51单片机串行口的问题

在Proteus下仿真AT89C51单片机的串行口的时候&#xff0c;Proteu不同版本下差别较大。     同样的程序&#xff0c;在7.8的老版本&#xff08;7.8版本的原理图仿真软件名称是ISIS 7 Professional&#xff09;下仿真串行口&#xff0c;收发均正常。但是&#xff0c;在8.13版…

打印lua输出日志

日志级别&#xff1a; ngx.STDERR 标准输出ngx.EMERG 紧急报错ngx.ALERT 报警ngx.CRIT 严重&#xff0c;系统故障&#xff0c; 触发运维告警系统ngx.ERR 错误&#xff0c;业务不可恢复性错误ngx.WARN 提醒&#xff0c; 业务中可忽略错误ngx.NOTICE 提醒&#xff0c; 业务中比较…

增速大幅下滑?基础L2博弈成本

在高阶智驾&#xff08;从ALC到NOA&#xff09;的光环之下&#xff0c;传统入门级基础L2级辅助驾驶赛道也在发生一些微妙的变化。 高工智能汽车研究院监测数据显示&#xff0c;2023年1-9月&#xff0c;基础L2在中国市场&#xff08;不含进出口&#xff09;乘用车前装标配交付45…

数据库存储引擎

一、MySQL体系结构 二、存储引擎-简介 存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表的&#xff0c;而不是基于库的&#xff0c;所以存储引擎也可以被成为表的类型 MySQL 5.5版本之后&#xff0c;默认存储引擎就是InnoDB&#xff0c;之前…