2025年条件变量使用场景(条件变量使用场景有哪些)

条件变量使用场景(条件变量使用场景有哪些)svg xmlns http www w3 org 2000 svg style display none svg

大家好,我是讯享网,很高兴认识大家。



 <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> 

讯享网

在Go中,条件控制语句总共有三种,,。

相对前两者而言比较特殊

至多两个判断分支,语句格式如下

讯享网

必须是一个布尔表达式,即结果要么为真要么为假,必须是一个布尔值

同时语句也可以包含一些简单的语句,例如:

 

if语句相较于其他语言的if语句,基本一致

不同点在于

  • 判断的式子并不需要用括号括起来
  • 可以在判断式子里可以进行赋值声明变量的操作

语句也是一种多分支的判断语句,语句格式如下:

讯享网

一个简单的例子如下

 

还可以在表达式之前编写一些简单语句,例如声明新变量

讯享网

语句也可以没有入口处的表达式。

 

通过关键字来继续执行相邻的下一个分支。

讯享网

与其他语言的switch不同的是,在Go中,switch循环可以不用判断句子,直接进入判断

标签语句,给一个代码块打上标签,可以是,,的目标。例子如下:

 

单纯的使用标签是没有任何意义的,需要结合其他关键字来进行使用。

将控制权传递给在同一函数对应标签的语句,示例如下:

讯享网

在实际应用中用的很少,跳来跳去的很降低代码可读性,性能消耗也是一个问题。

在Go中,有且仅有一种循环语句 for

Go抛弃了while循环,因为for可以被当作while循环来使用

 

当只保留循环条件时,就变成了。

讯享网

示例

这是一段输出区间数字的代码

 

你可以同时初始化多个变量,然后将其递增

讯享网

双循环打印九九乘法表,这是一个很经典的循环案例

 

输出如下

讯享网
 

如果没有其他因素,可以直接放 布尔类型 做表达式,充当while循环

讯享网

输出:

 
讯享网

是不是有点简单?下面有请 切片 登场!(股掌声!)

在Go中,数组和切片两者看起来长得几乎一模一样,但功能有着不小的区别,数组是定长的数据结构,长度被指定后就不能被改变,而切片是不定长的,切片在容量不够时会自行扩容

如果事先就知道了要存放数据的长度,且后续使用中不会有扩容的需求,就可以考虑使用数组,Go中的数组是值类型,而非引用,并不是指向头部元素的指针

数组作为值类型,将数组作为参数传递给函数时,由于Go函数是传值传递,所以会将整个数组拷贝


讯享网

 

以上几种方式都会给分配一片固定大小的内存,区别只是最后一种得到的值是指针。

在数组初始化时,需要注意的是,长度必须为一个常量表达式,否则将无法通过编译,常量表达式即表达式的最终结果是一个常量

讯享网

使用数组的下标就可以访问数组中对应的元素,同样的,也可以修改数组中的元素

 
  • len函数:返回数组的元素数量
  • cap函数:返回数组的容量,相当于数组长度。容量对于切片才有意义
讯享网

切割数组的格式为,切割的区间为左闭右开

根据下标来对数组中的值进行切割。

  • 数组在切割后,会变成切片类型

若要将数组转换为切片类型,不带参数进行切片即可,转换后的切片与原数组指向的是同一片内存,修改切片会导致原数组内容的变化

 

切片在Go中的应用范围要比数组广泛的多,它用于存放不知道长度的数据,且后续使用过程中可能会频繁的插入和删除元素

讯享网

我们能够看到,切片的初始化可以说跟数组没什么区别,仅仅抛弃了一个初始化长度。

在使用切片时,更加推荐使用 make() 创建一个空切片。

  • 函数接收三个参数:类型,长度,容量。

切片的长度代表着切片中元素的个数,切片的容量代表着切片总共能装多少个元素

切片的底层实现依旧是数组,是引用类型,可以简单理解为是指向底层数组的指针

  • 为什么会更推荐 make() 函数创建切片呢?

通过这种方式声明的切片,默认值为,所以不会为其分配内存,而在使用进行初始化时,建议预分配一个足够的容量,可以有效减少后续扩容的内存消耗。

其实和Go开发的中心思想一致,做到创建足够用的变量。

遵守 用多少 就创建多少的原则,例如:能用int8类型的数组就用int8,尽量收缩内存空余

 

切片的基本使用与数组完全一致,区别只是切片可以动态变化长度

切片可以通过函数实现许多操作,函数签名如下,是要添加元素的目标切片,是待添加的元素,返回值是添加后的切片。

切片元素的插入也是需要结合函数来使用

讯享网

以上例子的插入已经是最简化

切片元素的删除需要结合函数来使用

  • 为什么要配合append函数?

    append() 方法,其实底子里是一种赋值操作,添加也是直接进行了替换操作

    如果没有设置开始索引,那么它默认是从最后插入,

 

切片在拷贝时需要确保目标切片有足够的长度

讯享网

切片遍历与数组完全一致,就不细讲了

 
讯享网

make()函数在创建二维数组的时候,并不会为切片中添加默认值

所以,在以make()函数创建多维数组的时候,还需要单独初始化

  • 因为make函数只会帮你初始化最开始的那一层,二维之后的内容需要自己单独初始化
 

tips:在数组未初始化前,我们无法对数组做任何与值有关的操作

报错:

讯享网

只有切片才能使用拓展表达式

切片与数组都可以使用简单表达式来进行切割,但是拓展表达式只有切片能够使用,该特性于Go1.2版本添加,主要是为了解决切片共享底层数组的读写问题,主要格式为如下,需要满足关系,使用拓展表达式切割的切片容量为

 

那么这么做就会有一个明显的问题,与是共享的同一个底层数组,在对进行读写时,有可能会影响的的数据

讯享网

slice表达式分为简单表达式slice[low,high]和扩展表达式slice[low : high : max];

简单表达式作用于数组、切片时产生新的切片,作用于字符串时产生新的字符串;

扩展表达式只能作用于数组、切片,不能作用于字符串。

tips:

新切片b ( b := a[low, high])不仅可以读写a[low]至a[high-1]之间的所有元素,而且在使用append(b, x)函数增加新的元素x时,还可能会覆盖a[high]及后面的元素

在go1.21新增了内置函数,clear会将切片内所有的值置为零值,

 

如果想要清空切片,可以用拓展表达式

讯享网

限制了切割后的容量,这样可以避免覆盖原切片的后续元素。

一般来说,映射表数据结构实现通常有两种,哈希表(hash table)和搜索树(search tree),区别在于前者无序,后者有序。在Go中,的实现是基于哈希桶(也是一种哈希表),所以也是无序的。

在Go中,map的键类型必须是可比较的,比如,是可比较的,而是不可比较的,也就无法作为map的键。

6.1.1 字面量初始化

 
讯享网

6.1.2 make 函数初始化

使用内置函数,对于map而言,接收两个参数,分别是类型与初始容量

 

6.1.3 tips

map是引用类型,零值或未初始化的map可以访问,但是无法存放元素,所以必须要为其分配内存

讯享网

在初始化map时应当尽量分配一个合理的容量,以减少扩容次数。

还是Go的一种规范,尽力减少内存消耗

访问一个map的方式就像通过索引访问一个数组一样

 

通过代码可以观察到,即使map中不存在这一键值对,但依旧有返回值。

map对于不存的键其返回值是对应类型的零值,并且在访问map的时候其实有两个返回值,第一个返回值对应类型的值,第二个返回值一个布尔值,代表键是否存在

讯享网

求长度,还是使用len()方法。

其实把这个当作js中的length属性就可以了

 

map的存值与数组存值类似

存储已经存在的键时,会覆盖掉原有的值

讯享网

不过,也有个特殊情况:

 

通过结果可以观察到相同的键值并没有覆盖,反而还可以存在多个,也无法判断其是否存在,也就无法正常取值。

因为NaN是IEE754标准所定义的,其实现是由底层的汇编指令完成,这是一个无序比较双精度浮点数的指令,该指令会考虑到NaN的情况,因此结果就是任何数字都不等于NaN,NaN也不等于自身,这也造成了每次哈希值都不相同。关于这一点社区也曾激烈讨论过,但是官方认为没有必要去修改

总归一句话,尽量避免使用NaN作为map的键。

讯享网

删除一键值对需要用到内置函数,例如

 

需要注意的是,如果值为NaN,甚至没法删除该键值对。

讯享网

在go1.21之前,想要清空map,就只能对每一个map的key进行delete

但是go1.21更新了clear函数,就不用再进行之前的操作了,只需要一个clear就可以清空

 

map并不是一个并发安全的数据结构,Go团队认为大多数情况下map的使用并不涉及高并发的场景,引入互斥锁会极大的降低性能

map内部有读写检测机制,如果冲突会触发。例如下列情况有非常大的可能性会触发

讯享网

在这种情况下,需要使用来替代。

  1. Go的环境安装与开发工具配置
  2. Go的运行流程步骤与包的概念
  3. (Go)变量与常量?字面量与变量的较量!
  4. 初上手Go?本篇文章帮拿捏Go的数据类型!

  • 还不了解Git分布式版本控制器?本文将带你全面了解并掌握
  • 带你认识Maven的依赖、继承和聚合都是什么!有什么用?
  • 2-3树思想与红黑树的实现与基本原理
  • !全网最全! ElasticSearch8.7 搭配 SpringDataElasticSearch5.1 的使用
  • 全面深入Java GC!!带你完全了解 GC垃圾回收机制!!
  • 全面了解Java的内存模型(JMM)!详细清晰!
  • 在JVM中,类是如何被加载的呢?本篇文章就带你认识类加载的一套流程!

全文资料学习全部参考于:Golang中文学习文档

小讯
上一篇 2025-05-24 10:43
下一篇 2025-04-28 15:22

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/152912.html